matplotlib中的轴标签与刻度标签对齐

k5hmc34c  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(354)

由于空间的原因,我有时会以下列样式绘制出图:

fig, ax = plt.subplots(figsize=(3, 3))
ax.plot([0,1], [1000, 1001])
ax.set_xticks([0, 1])
ax.set_yticks([1000, 1001])
ax.set_xlabel("x", labelpad=-8)
ax.set_ylabel("y", labelpad=-18)

在这里,我只保留了标记X/Y域边界的刻度,并使用labelpad关键字参数手动对齐xlabelylabel,以便x和y轴标签与刻度标签直观对齐。
请注意,我不得不对不同的轴使用不同的填充量,因为y刻度标签10001001的长度比x刻度标签01的高度更远离轴,而且x轴标签的垂直位置和y轴标签的水平位置都是相对于它们的通常位置而言的,其将刚好超过刻度标签的范围。
我想知道,是否有一种方法可以自动执行此过程,并且可以精确地执行,而不是直观地执行?例如,如果labelpad相对于脊线,这将是非常好的,或者如果有一种方法可以确定刻度和刻度标签远离脊线的范围,该数字也可以用于自动执行此操作。
使用ax.yaxis.set_label_coords可以获得类似的效果,但这会相对于轴的变换来变换位置,因此取决于轴的大小,而记号是相对于脊线绝对定位的。

jecbmhm3

jecbmhm31#

您使用ax.{x,y}axis.set_label_coords所要遵循的路径几乎就在那里!您所需要做的就是将transAxes转换 Package 在offset_copy中,然后提供一个偏移量,该偏移量是当前tick长度+tick bbox周围任何空格的组合。

使用转换

import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy

fig, ax = plt.subplots(figsize=(3, 3))
fig.set_facecolor('white')

ax.plot([0,1], [1000, 1001])
ax.set_xticks([0, 1])
ax.set_yticks([1000, 1001])

# Create a transform that vertically offsets the label
#   starting at the edge of the Axes and moving downwards 
#   according to the total length of the bounding box of a major tick
t = offset_copy(
    ax.transAxes, y=-(ax.xaxis.get_tick_padding() + ax.xaxis.majorTicks[0].get_pad()),
    fig=fig, units='dots'
)
ax.xaxis.set_label_coords(.5, 0, transform=t)
ax.set_xlabel('x', va='top')

# Repeat the above, but on the y-axis
t = offset_copy(
    ax.transAxes, x=-(ax.yaxis.get_tick_padding() + ax.yaxis.majorTicks[0].get_pad()),
    fig=fig, units='dots'
)
ax.yaxis.set_label_coords(0, .5, transform=t)
ax.set_ylabel('y', va='bottom')

使用较长的分笔成交点进行测试

import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy

fig, ax = plt.subplots(figsize=(3, 3))
fig.set_facecolor('white')

ax.plot([0,1], [1000, 1001])
ax.set_xticks([0, 1])
ax.set_yticks([1000, 1001])
ax.xaxis.set_tick_params(length=10)
ax.yaxis.set_tick_params(length=15)

t = offset_copy(
    ax.transAxes, y=-(ax.xaxis.get_tick_padding() + ax.xaxis.majorTicks[0].get_pad()), 
    fig=fig, units='points'
)
ax.xaxis.set_label_coords(.5, 0, transform=t)
ax.set_xlabel('x', va='top')

t = offset_copy(
    ax.transAxes, x=-(ax.yaxis.get_tick_padding() + ax.yaxis.majorTicks[0].get_pad()),
    fig=fig, units='points'
)
ax.yaxis.set_label_coords(0, .5, transform=t)
ax.set_ylabel('y', va='bottom')

更长的滴答声和更高的DPI

import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy

fig, ax = plt.subplots(figsize=(3, 3), dpi=150)
fig.set_facecolor('white')

ax.plot([0,1], [1000, 1001])
ax.set_xticks([0, 1])
ax.set_yticks([1000, 1001])
ax.xaxis.set_tick_params(length=10)
ax.yaxis.set_tick_params(length=15)

t = offset_copy(
    ax.transAxes, y=-(ax.xaxis.get_tick_padding() + ax.xaxis.majorTicks[0].get_pad()), 
    fig=fig, units='points'
)
ax.xaxis.set_label_coords(.5, 0, transform=t)
ax.set_xlabel('x', va='top')

t = offset_copy(
    ax.transAxes, x=-(ax.yaxis.get_tick_padding() + ax.yaxis.majorTicks[0].get_pad()), 
    fig=fig, units='points'
)
ax.yaxis.set_label_coords(0, .5, transform=t)
ax.set_ylabel("y", va='bottom')

相关问题