Matplotlib:使用子批次行标签的所有子批次的自动彩色图例

2024-04-19 06:02:59 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码实现了我想做的事情,但这是一种非常迂回的方式。我四处寻找一种简洁的方法来为一个图形生成一个单独的图例,该方法包含多个子图块,并考虑到它们的标签,但都没有用。plt.figlegend()需要传入标签和行,plt.legend()只需要句柄(稍微好一点)。在

下面的例子说明了我想要什么。我有9个向量,每个向量有3个类别。我想在一个单独的子图上绘制每个向量,给它贴上标签,并绘制一个图例,用颜色表示标签的含义;这是单个绘图上的自动行为。在

你知道有更好的方法来实现下面的情节吗?在

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

nr_lines = 9
nr_cats = 3
np.random.seed(1337)

# Data
X = np.random.randn(nr_lines, 100)
labels = ['Category {}'.format(ii) for ii in range(nr_cats)]
y = np.random.choice(labels, nr_lines)

# Ideally wouldn't have to manually pick colours
clrs = matplotlib.rcParams['axes.prop_cycle'].by_key()['color']
clrs = [clrs[ii] for ii in range(nr_cats)]
lab_clr = {k: v for k, v in zip(labels, clrs)}

fig, ax = plt.subplots(3, 3)
ax = ax.flatten()
for ii in range(nr_lines):
    ax[ii].plot(X[ii,:], label=y[ii], color=lab_clr[y[ii]])

lines = [a.lines[0] for a in ax]
l_labels = [l.get_label() for l in lines]

# the hack - get a single occurance of each label
idx_list = [l_labels.index(lab) for lab in labels]
lines_ = [lines[idx] for idx in idx_list]
#l_labels_ = [l_labels[idx] for idx in idx_list]
plt.legend(handles=lines_, bbox_to_anchor=[2, 2.5])
plt.tight_layout()
plt.savefig('/home/james/Downloads/stack_figlegend_example.png',
            bbox_inches='tight')

Example plot with 9 lines and 3 categories. Each category has a different colour


Tags: 方法inforlabelsnplabplt标签
1条回答
网友
1楼 · 发布于 2024-04-19 06:02:59

你可以用字典把标签作为关键字来收集它们。例如:

handles = {}

for ii in range(nr_lines):
    l1, = ax[ii].plot(X[ii,:], label=y[ii], color=lab_clr[y[ii]])

    if y[ii] not in handles:
        handles[y[ii]] = l1

plt.legend(handles=handles.values(), bbox_to_anchor=[2, 2.5])

仅当类别尚未存在时才向字典添加句柄。在

相关问题 更多 >