matplotlib中的图例中有多个标题

时间:2014-07-16 17:26:34

标签: python matplotlib plot label legend

是否可以放置多个"标题"在matplotlib的传奇? 我想要的是:

Title 1
x label 1
o label2

Title 2
^ label 3
v label 4

...

如果我有4条曲线或更多。因为如果我使用多个图例,很难让它们正确对齐,手动设置位置。

2 个答案:

答案 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))

作为一个例子,我得到了以下图例(裁剪掉图像的其余部分)。 enter image description here