是否可以放置多个"标题"在matplotlib的传奇? 我想要的是:
Title 1
x label 1
o label2
Title 2
^ label 3
v label 4
...
如果我有4条曲线或更多。因为如果我使用多个图例,很难让它们正确对齐,手动设置位置。
答案 0 :(得分:3)
我最接近它的是创建一个空的代理艺术家。我认为有问题 是因为它们没有左对齐,但(空)标记的空间仍然存在。
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 1, 100)
# the comma is to get just the first element of the list returned
plot1, = plt.plot(x, x**2)
plot2, = plt.plot(x, x**3)
title_proxy = Rectangle((0,0), 0, 0, color='w')
plt.legend([title_proxy, plot1, title_proxy, plot2],
["$\textbf{title1}$", "label1","$\textbf{title2}$", "label2"])
plt.show()
答案 1 :(得分:0)
好的,所以我需要回答这个问题,目前的答案对我不起作用。在我的情况下,我事先不知道我在图例中“经常”需要一个标题。这取决于一些输入变量,所以我需要比手动设置标题位置更灵活的东西。在访问了这里的数十个问题之后,我找到了这个对我来说非常适合的解决方案,但也许有更好的方法。
## this is what changes sometimes for me depending on how the user decided to input
parameters=[2, 5]
## Titles of each section
title_2 = "\n$\\bf{Title \, parameter \, 2}$"
title_4 = "\n$\\bf{Title \, parameter \, 4}$"
title_5 = "\n$\\bf{Title \, parameter \, 5}$"
def reorderLegend(ax=None, order=None):
handles, labels = ax.get_legend_handles_labels()
info = dict(zip(labels, handles))
new_handles = [info[l] for l in order]
return new_handles, order
#########
### Plots
fig, ax = plt.subplots(figsize=(10, 10))
ax.set_axis_off()
## Order of labels
all_labels=[]
if 2 in parameters:
ax.add_line(Line2D([], [], color="none", label=title_2))
all_labels.append(title_2)
#### Plot your stuff below header 2
#### Append corresponding label to all_labels
if 4 in parameters:
ax.add_line(Line2D([], [], color="none", label=title_4))
all_labels.append(title_4)
#### Plot your stuff below header 4
#### Append corresponding label to all_labels
if 5 in parameters:
ax.add_line(Line2D([], [], color="none", label=title_5))
all_labels.append(title_5)
#### Plot your stuff below header 5
#### Append corresponding label to all_labels
## Make Legend in correct order
handles, labels = reorderLegend(ax=ax, order=all_labels)
leg = ax.legend(handles=handles, labels=labels, fontsize=12, loc='upper left', bbox_to_anchor=(1.05, 1), ncol=1, fancybox=True, framealpha=1, frameon=False)
## Move titles to the left
for item, label in zip(leg.legendHandles, leg.texts):
if label._text in [title_2, title_4, title_5]:
width=item.get_window_extent(fig.canvas.get_renderer()).width
label.set_ha('left')
label.set_position((-2*width,0))