手动设置图例中点的颜色

53 投票
5 回答
111787 浏览
提问于 2025-04-18 06:46

我正在制作一个散点图,效果如下:

在这里输入图片描述

(问题底部有最小可重现示例)

从上面的图片可以看到,图例中的点的颜色是由 matplotlib 自动设置为蓝色的。我需要把这些点的颜色改成其他不在颜色映射中的颜色(比如:黑色),这样就不会和颜色映射中的颜色混淆了。

我查了一下,但 matplotlib.legend 模块似乎不支持 color 这个参数。有没有办法做到这一点呢?


这是最小可重现示例:

import matplotlib.pyplot as plt
import numpy as np

def rand_data():
    return np.random.uniform(low=0., high=1., size=(100,))

# Generate data.
x, y, x2, x3 = [rand_data() for i in range(4)]
# This data defines the markes and labels used.
x1 = np.random.random_integers(7, 9, size=(100,))

# Order all lists so smaller points are on top.
order = np.argsort(-np.array(x2))
# Order x and y.
x_o, y_o = np.take(x, order), np.take(y, order)
# Order list related to markers and labels.
z1 = np.take(x1, order)
# Order list related to sizes.
z2 = np.take(x2, order)
# Order list related to colors.
z3 = np.take(x3, order)

plt.figure()
cm = plt.cm.get_cmap('RdYlBu')

# Scatter plot where each value in z1 has a different marker and label
# assigned.
mrk = {7: ('o', '7'), 8: ('s', '8'), 9: ('D', '9')}
for key, value in mrk.items():

    s1 = (z1 == key)
    plt.scatter(x_o[s1], y_o[s1], marker=value[0], label=value[1],
        s=z2[s1] * 100., c=z3[s1], cmap=cm, lw=0.2)

# Plot colorbar
plt.colorbar()

# Plot legend.
plt.legend(loc="lower left", markerscale=0.7, scatterpoints=1, fontsize=10)

plt.show()

5 个回答

1

关于@Saullo G. P. Castro的回答:

这是一个警告信息:legendHandles这个属性在Matplotlib 3.7版本中被弃用了,以后会在两个小版本更新后被删除。请改用legend_handles。


将来的使用方法:

ax = plt.gca()
leg = ax.get_legend()
leg.legend_handles[0].set_color('red')
leg.legend_handles[1].set_color('yellow')
1

虽然我发现用 legendHandles[i].set_color 的方法对 errorbar 不管用,但我找到了一种替代的方法:

ax_legend = fig.add_subplot(g[3, 0])
ax_legend.axis('off')
handles_markers = []
markers_labels = []
for marker_name, marker_style in markers_style.items():
    pts = plt.scatter([0], [0], marker=marker_style, c='black', label=marker_name)
    handles_markers.append(pts)
    markers_labels.append(marker_name)
    pts.remove()
ax_legend.legend(handles_markers, markers_labels, loc='center', ncol=len(markers_labels), handlelength=1.5, handletextpad=.1)

你也可以看看 这个GitHub问题

3

如果你想把颜色和特定的标签对应起来,可以用 lh.get_label() 来获取每个图例的标签。

对我来说,最好的办法是从 legendHandles 创建一个字典,然后像这样改变颜色:

ax = plt.gca()
leg = ax.get_legend()
hl_dict = {handle.get_label(): handle for handle in leg.legendHandles}
hl_dict['9'].set_color('red')
hl_dict['8'].set_color('yellow')
10

补充一下其他回答——我之前在用 set_color 改变图例标记颜色时遇到过麻烦。一个替代的方法是自己手动创建图例:

import matplotlib.lines as mlines

eight = mlines.Line2D([], [], color='blue', marker='s', ls='', label='8')
nine = mlines.Line2D([], [], color='blue', marker='D', ls='', label='9')
# etc etc
plt.legend(handles=[eight, nine])

从头开始制作图例有时候可以避免处理已经创建好的图例中的一些复杂问题。更多信息可以在 Matplotlib 的文档中找到,点击这里

75

你可以获取图例的句柄,并单独改变它们的颜色:

ax = plt.gca()
leg = ax.get_legend()
leg.legendHandles[0].set_color('red')
leg.legendHandles[1].set_color('yellow')

撰写回答