matplotlib标签不同大小的子图与每个子图的角完全相同

问题描述 投票:0回答:4

我正在寻找一种优雅的解决方案,使用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)

enter image description here

但是,如果绘图的大小不同,您将获得远离绘图角落的标签(由于纵横比)。例如,参见标签A和C.我正在寻找一种好方法来确保标签与包含多个尺寸/纵横比子图的面板的轴角成比例,和/或从轴角明确设置文本特定距离(以英寸或可能是图形坐标单位)。

在过去,我已经在面板中的每个子绘图轴的角落放置了相同大小的方形轴,使这些轴不可见,并将缩放文本设置为这些,但这是一种复杂的方法。

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)

enter image description here

python matplotlib annotate
4个回答
1
投票

您可以获取每个子图的位置并在图级上添加文本,以便偏移量在图形大小的分数中 - 对于所有子图都是相等的:

X = a.get_position().x0
Y = a.get_position().y1    
fig.text(X - .04, Y + .015, l, size=15, weight='bold')

结果:enter image description here


2
投票

您可以使用qazxsw poi而不是qazxsw poi作为参考,并添加单独的高度来补偿参考原点左下角:

这里为了简洁起见,只有循环中更改的行,其余代码未触及:

axes pixels

axes fraction


1
投票

那么简单地添加子图的标题呢?

(再次只是你的循环中要替换的行:)

    a.annotate(l, xy=(-40, 10 + a.bbox.height), xycoords="axes pixels", fontsize=15, weight = 'bold')

结果:enter image description here


0
投票

虽然上述两种解决方案都有效(并且更简单/满足大多数人的需求),但我认为我会发布一个拼凑在一起的解决方案,允许您放置与特定轴点精确英寸/偏移点的文本/对象。这意味着无论图形面板大小/ dpi如何,文本都可以与角落放置相同的距离 - 如果制作不同尺寸的多个图形并且希望它们保持一致(例如用于发布)则是有用的。显然,a.set_title(l, size=15, weight='bold', loc='left') 功能是为此目的而设计的,允许指定英寸,点(1/72英寸)或点作为偏移。

HTTPS://mat plot lib.org/examples/便宜啦吧_examples/trans offset.HTML

enter image description here

matplotlib.transforms.offset_copy()

或者用figsize / dpi改变了

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')

© www.soinside.com 2019 - 2024. All rights reserved.