matplotlib 图例透明度,使用次轴时

rur96b6h  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(135)

第二个轴的图例对另一个轴的图是透明的。一个重现这个问题的最小例子:

import matplotlib.pyplot as plt

ax1 = plt.subplot(111)
ax2 = ax1.twinx()
ax2.plot([1, 2, 3], [0.3, 0.2, 0.1], 'r')  
ax1.plot([1, 2, 3], [1, 2, 3], 'b', label='ax1')
ax1.legend(loc=2)
plt.show()

我得到的输出是:x1c 0d1x
正如你所看到的,蓝色图的图例被红色图覆盖了。重新排列绘图命令,更改alpha值或更改对象的z顺序都没有帮助。
有没有办法让图例对所有图都不透明?
编辑:@tcaswell:虽然你的答案只适用于一个图例,但如果两个轴都有单独的图例,它就不起作用了。在下面的代码中,我为ax2添加了一个标签:

import matplotlib.pyplot as plt
plt.figure()
ax1 = plt.subplot(111)
ax2 = ax1.twinx()
ax2.plot([1, 2, 3], [0.3, 0.2, 0.1], 'r', label='ax2')  
ax1.plot([1, 2, 3], [1, 2, 3], 'b', label='ax1')
ax1.legend(loc=2)
ax2.legend(loc=1)

ax1.set_zorder(1) # make it on top
ax1.set_frame_on(False) # make it transparent
ax2.set_frame_on(True) # make sure there is any background

plt.show()

结果如下:

虽然您的更通用的方法解决了这个问题,但不幸的是,使用Figure.legend将图例放置在图的外部。使用loc显式放置图例有点繁琐,并且在缩放图时效果不佳。有更好的解决方案吗?

3zwjbxry

3zwjbxry1#

由于matplotlib渲染图的方式,你遇到了问题。默认情况下,第二个轴在第一个轴之后渲染(它们具有相同的zorder,因此它们按照添加的顺序渲染)。
为了得到你想要的,你只需要调整你的轴的一些东西:

figure()
ax1 = plt.subplot(111)
ax2 = ax1.twinx()
ax2.plot([1, 2, 3], [0.3, 0.2, 0.1], 'r')  
ax1.plot([1, 2, 3], [1, 2, 3], 'b', label='ax1')
ax1.legend(loc=2)

ax1.set_zorder(1) # make it on top
ax1.set_frame_on(False) # make it transparent
ax2.set_frame_on(True) # make sure there is any background

plt.show()

我们将ax1zorder设置得更高,以便稍后渲染,但是如果我们这样做,第二个轴根本不可见,因为它都绘制在框架下(白色背景和方框)。为了解决这个问题,我们关闭了ax1上的帧(所以我们可以看到ax2)。然而,现在我们根本没有背景或边界框。然后我们可以重新打开ax2的帧,这给了我们想要的效果。
上面的方法是临时的,不是通用的,如果你想确保你的轴在所有轴之上,你需要使用Figure.legend(),这是一个figure,而不是axes功能。目前,它不会自动神奇地找到你的标签,所以你必须显式地传入句柄和标签:

fig = figure()

ax1 = plt.subplot(111)
ax2 = ax1.twinx()

ln2, = ax2.plot([1, 2, 3], [0.3, 0.2, 0.1], 'r', label='ax2')  
ln1, = ax1.plot([1, 2, 3], [1, 2, 3], 'b', label='ax1')

interesting_lines = [ln1, ln2]

fig.legend(*zip(*[(il, il.get_label()) for il in interesting_lines]), loc=2)

plt.show()

请注意,此图例现在使用 figure 坐标放置。

u59ebvdq

u59ebvdq2#

我使用bbox_to_锚来设置两个图例的位置,它们出现在顶部。不知道为什么,但它工作了。例如:

ax1.legend(bbox_to_anchor=(0.16,0.2))
ax2.legend(bbox_to_anchor=(1,0.2))

相关问题