辅助轴图的图例以某种方式对另一轴的图是透明的。重现问题的最小例子:
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()
我得到的输出是:
正如你所看到的,蓝色情节的传说被红色阴谋透支了。重新排列绘图命令,更改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
显式放置它们有点单调乏味,在缩放绘图时效果不佳。有更好的解决方案吗?
答案 0 :(得分:8)
由于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()
我们将zorder
的{{1}}设置为更高,以便稍后渲染,但如果我们这样做,则第二个轴根本不可见,因为它在框架下绘制ax1
的(白色背景和方框)。为了解决这个问题,我们在ax1
上关闭了框架(因此我们可以看到ax1
)。但是,现在我们根本没有没有背景或边界框。然后我们可以将框架重新打开ax2
,这会给我们带来理想的效果。
上面的方法是临时的而不是一般的,如果你想确保你的轴在所有轴之上,你需要使用ax2
,这是一个{{1 }},而不是Figure.ledgend()
功能。目前,它不会自动神奇地找到您的标签,因此您必须明确地传递句柄和标签:
figure
请注意,此图例现在使用 figure 坐标放置。
答案 1 :(得分:0)
我使用bbox_to_anchor来设置两个图例的位置,它们出现在顶部。不知道为什么,但它奏效了。 例如:
ax1.legend(bbox_to_anchor=(0.16,0.2))
ax2.legend(bbox_to_anchor=(1,0.2))