#python-3.x #matplotlib #legend
#python-3.x #matplotlib #легенда
Вопрос:
Я хочу построить легенду на отдельном кадре, отличном от исходного графика. Я могу построить легенду из команд построения графика. Но не легенда из 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
Любой намек на это исправить?
Комментарии:
1. Вам нужны 2 подзаголовка? Как здесь , в примере после «или если вы хотите иметь 2 подзаголовка»?
2. Нет, мне нужна легенда на отдельном графике, чтобы поместить ее отдельно в PowerPoint.
3. Вы можете поместить заливку между новыми осями, а затем установить границы просмотра, чтобы она не была видна.
4. Да, я могу нарисовать легенду поверх 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
.
Комментарии:
1. Хорошо, воссоздаем новый, но более простой объект с тем же цветом, альфа и т.д… это хороший обходной путь. Спасибо за эту идею, я буду ее использовать. В любом случае, я все еще чувствую, что это обходной путь, и что его не следует добавлять. Оливье
2. @Marti На самом деле это ручной метод, который можно использовать для решения всех требований к созданию сложных легенд, которые вы найдете в реальной жизни. Вы узнали, что автоматический подход имеет ограничения. В вашем случае
fill0
(в отличиеline1
от иline2
которые просты) не разрешается повторно использовать, чтобы избежать проблемы графического рендеринга в текущей версии matplotlib.