在单独的图上绘制图例时出错
Posted
技术标签:
【中文标题】在单独的图上绘制图例时出错【英文标题】:Error when drawing a legend on a separate plot 【发布时间】:2021-01-20 08:50:03 【问题描述】:我想在与原始图不同的框架上绘制图例。我可以从绘图命令中绘制图例。但不是来自 fill_between 的传说。
这是一个示例代码
#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
xx = np.linspace(0, 3.14*3, 100)
yy = np.sin (xx)
zz = yy +0.5
# I can draw a plot with legend
fig = plt.figure( )
ax = fig.add_subplot(1, 1, 1,)
line1, = ax.plot (xx, yy, label='xx')
line2, = ax.plot (xx, zz, label='yy')
fill0 = ax.fill_between (xx, yy, zz, label='filling', alpha=0.2, color='grey' )
ax.legend ( handles=[line1, line2, fill0])
plt.show()
# I can draw a empty plot with the legend of the lines
plt.legend(handles=[line1, line2])
plt.show()
# I can't draw an empty plot with the legend of the fill
# Why ?
# Can I fix this ?
plt.legend(handles=[fill0,])
plt.show()
现在是错误:
Traceback (most recent call last):
File "Untitled.py", line 34, in <module>
plt.legend(handles=[fill0,])
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/pyplot.py", line 2721, in legend
return gca().legend(*args, **kwargs)
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/axes/_axes.py", line 417, in legend
self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/legend.py", line 503, in __init__
self._init_legend_box(handles, labels, markerfirst)
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/legend.py", line 767, in _init_legend_box
fontsize, handlebox))
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/legend_handler.py", line 117, in legend_artist
fontsize, handlebox.get_transform())
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib /legend_handler.py", line 727, in create_artists
self.update_prop(p, orig_handle, legend)
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/legend_handler.py", line 76, in update_prop
legend._set_artist_props(legend_handle)
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/legend.py", line 550, in _set_artist_props
a.set_figure(self.figure)
File "/Users/marti/anaconda3/envs/PROD/lib/python3.7/site-packages/matplotlib/artist.py", line 704, in set_figure
raise RuntimeError("Can not put single artist in "
RuntimeError: Can not put single artist in more than one figure
有什么提示可以解决这个问题吗?
【问题讨论】:
你想要 2 个子图吗?就像示例中的here“或者如果你想拥有2个子图”? 不,我需要将图例放在单独的图上,以便将其单独放在 PowerPoint 中。 您可以在新轴之间放置一个填充,然后设置视图限制使其不可见。 是的,我可以在 fill_between 上绘制图例。我将这样做。但我对此并不十分满意:-(( 【参考方案1】:所涉及的artist
对象具有深层嵌套数据,matplotlib 选择不允许其在其他轴上重复使用。解决方法代码可以是这样的:
(这里只给出接近尾声的相关代码)
# if want to plot the filled patch, must create anew
grey_patch1 = mpatches.Patch(label='filling1', alpha=0.2, color='grey')
plt.legend(handles=[line1, line2, grey_patch1])
plt.show()
#grey_patch1 can be reused, no need to recreate like this
grey_patch2 = mpatches.Patch(label='filling2', alpha=0.2, color='red')
plt.legend(handles=[grey_patch1, grey_patch2,])
plt.show()
以上代码需要import matplotlib.patches as mpatches
。
【讨论】:
好的,用相同的颜色、alpha 等重新创建一个新的但更简单的对象......是一个很好的解决方法。谢谢你的想法,我会用的。无论如何,我仍然觉得这是一种解决方法,它不应该附加。奥利维尔 @Marti 实际上它是一种手动方法,可用于解决您在现实生活中会发现的复杂图例制作的所有要求。您已经了解到自动方法有局限性。在您的情况下,fill0
(与简单的line1
和line2
不同)不允许重用,以避免在当前版本的 matplotlib 中出现图形渲染问题。以上是关于在单独的图上绘制图例时出错的主要内容,如果未能解决你的问题,请参考以下文章