matplotlib 标签不同大小的子图与每个子图的角的距离完全相同
matplotlib label subplots of different sizes the exact same distance from corner of each subplot
我正在寻找一种优雅的解决方案,使用 matplotlib 在每个子图的角上方放置图形标签(A、B、C),但每个子图轴角的距离都完全相同。我遇到的问题是典型的标签解决方案利用了坐标轴分数——因此很容易将 A、B、C 放置在相对于每个图的相同位置。
import matplotlib as mpl
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2, figsize = (10,10))
texts = ['A', 'B', 'C', 'D']
axes = fig.get_axes()
for a,l in zip(axes, texts):
a.annotate(l, xy=(-0.1, 1.1), xycoords="axes fraction", fontsize=15, weight = 'bold')
plt.suptitle('Label_Distance Consistent', fontsize = 20)
但是,如果图的大小不同,您将获得距离图的角落不等的标签(由于纵横比)。例如,参见标签 A 和 C。我正在寻找一种好方法来 确保包含多个 sizes/aspect 比率子图的面板的标签与轴角的比例距离,and/or 以明确设置文本特定距离(以英寸为单位或可能图坐标单位)从轴角。
过去我在面板中每个子图轴的角上放置了相同大小的方轴,使它们不可见,并将文本缩放到这些,但这是一种复杂的方法。
fig, ax = plt.subplots(2,2, figsize = (10,10))
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))
axes = fig.get_axes()
texts = ['A', 'B', 'C', 'D', 'E']
for a,l in zip(axes, texts):
a.annotate(l, xy=(-0.1, 1.1), xycoords="axes fraction", fontsize=15, weight = 'bold')
plt.suptitle('Label Distance Inconsistent', fontsize = 20)
您可以使用 axes pixels
代替 axes fraction
作为参考,并添加单独的高度以补偿参考原点左下角:
为简洁起见,此处仅更改循环中的行,其余代码保持不变:
a.annotate(l, xy=(-40, 10 + a.bbox.height), xycoords="axes pixels", fontsize=15, weight = 'bold')
简单地添加子图的标题怎么样?
(同样只有循环中要替换的行:)
a.set_title(l, size=15, weight='bold', loc='left')
您可以获得每个子图的位置并在图形级别添加文本,以便偏移量是图形大小的分数 - 这对所有子图都是相等的:
X = a.get_position().x0
Y = a.get_position().y1
fig.text(X - .04, Y + .015, l, size=15, weight='bold')
结果:
虽然上述两种解决方案都有效(而且 simple/meet 大多数人需要的更多),但我认为我会 post 拼凑出一个解决方案,让您可以放置 text/objects从特定轴点精确偏移 inches/points。这意味着无论图形面板 size/dpi,文本都可以放置在与角的距离相同的位置——如果制作多个不同尺寸的图形并希望它们保持一致(例如出版),这很有用。显然 matplotlib.transforms.offset_copy()
函数是为此目的而设计的,允许指定英寸、点(1/72 英寸)或点作为偏移量。
https://matplotlib.org/examples/pylab_examples/transoffset.html
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
fig, ax = plt.subplots(2,2, figsize = (10,7), dpi = 500)
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))
axes = fig.get_axes()
texts = ['A', 'B', 'C', 'D', 'E']
for a,l in zip(axes, texts):
a.set_xlim(0,10)
inv = a.transData.inverted()
# specify the number of points or inches or dots to transform by
# places an axes transform here for the axes on which you want to pick an anchor point on
offsetter = mpl.transforms.offset_copy(a.transAxes, fig=fig, x= -2, y= 6, units = 'points')
# offset an anchor point - this will return display coordinates
corner_offset = offsetter.transform([0,1])
# convert display coordinate to axes fraction
axes_frac = inv.transform(corner_offset)
a.annotate(l, xy=(axes_frac[0],axes_frac[1]), xycoords="axes fraction", fontsize=15, weight = 'bold', color='blue')
或用无花果size/dpi改变
我正在寻找一种优雅的解决方案,使用 matplotlib 在每个子图的角上方放置图形标签(A、B、C),但每个子图轴角的距离都完全相同。我遇到的问题是典型的标签解决方案利用了坐标轴分数——因此很容易将 A、B、C 放置在相对于每个图的相同位置。
import matplotlib as mpl
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2, figsize = (10,10))
texts = ['A', 'B', 'C', 'D']
axes = fig.get_axes()
for a,l in zip(axes, texts):
a.annotate(l, xy=(-0.1, 1.1), xycoords="axes fraction", fontsize=15, weight = 'bold')
plt.suptitle('Label_Distance Consistent', fontsize = 20)
但是,如果图的大小不同,您将获得距离图的角落不等的标签(由于纵横比)。例如,参见标签 A 和 C。我正在寻找一种好方法来 确保包含多个 sizes/aspect 比率子图的面板的标签与轴角的比例距离,and/or 以明确设置文本特定距离(以英寸为单位或可能图坐标单位)从轴角。
过去我在面板中每个子图轴的角上放置了相同大小的方轴,使它们不可见,并将文本缩放到这些,但这是一种复杂的方法。
fig, ax = plt.subplots(2,2, figsize = (10,10))
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))
axes = fig.get_axes()
texts = ['A', 'B', 'C', 'D', 'E']
for a,l in zip(axes, texts):
a.annotate(l, xy=(-0.1, 1.1), xycoords="axes fraction", fontsize=15, weight = 'bold')
plt.suptitle('Label Distance Inconsistent', fontsize = 20)
您可以使用 axes pixels
代替 axes fraction
作为参考,并添加单独的高度以补偿参考原点左下角:
为简洁起见,此处仅更改循环中的行,其余代码保持不变:
a.annotate(l, xy=(-40, 10 + a.bbox.height), xycoords="axes pixels", fontsize=15, weight = 'bold')
简单地添加子图的标题怎么样?
(同样只有循环中要替换的行:)
a.set_title(l, size=15, weight='bold', loc='left')
您可以获得每个子图的位置并在图形级别添加文本,以便偏移量是图形大小的分数 - 这对所有子图都是相等的:
X = a.get_position().x0
Y = a.get_position().y1
fig.text(X - .04, Y + .015, l, size=15, weight='bold')
结果:
虽然上述两种解决方案都有效(而且 simple/meet 大多数人需要的更多),但我认为我会 post 拼凑出一个解决方案,让您可以放置 text/objects从特定轴点精确偏移 inches/points。这意味着无论图形面板 size/dpi,文本都可以放置在与角的距离相同的位置——如果制作多个不同尺寸的图形并希望它们保持一致(例如出版),这很有用。显然 matplotlib.transforms.offset_copy()
函数是为此目的而设计的,允许指定英寸、点(1/72 英寸)或点作为偏移量。
https://matplotlib.org/examples/pylab_examples/transoffset.html
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
fig, ax = plt.subplots(2,2, figsize = (10,7), dpi = 500)
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))
axes = fig.get_axes()
texts = ['A', 'B', 'C', 'D', 'E']
for a,l in zip(axes, texts):
a.set_xlim(0,10)
inv = a.transData.inverted()
# specify the number of points or inches or dots to transform by
# places an axes transform here for the axes on which you want to pick an anchor point on
offsetter = mpl.transforms.offset_copy(a.transAxes, fig=fig, x= -2, y= 6, units = 'points')
# offset an anchor point - this will return display coordinates
corner_offset = offsetter.transform([0,1])
# convert display coordinate to axes fraction
axes_frac = inv.transform(corner_offset)
a.annotate(l, xy=(axes_frac[0],axes_frac[1]), xycoords="axes fraction", fontsize=15, weight = 'bold', color='blue')
或用无花果size/dpi改变