如何更改图例标记的颜色?

时间:2021-02-22 15:35:28

标签: python matplotlib

我正在尝试将图例项的颜色更改为黑色。我过去曾用 scatter 而不是 plot 做过类似的事情,但由于我也想要 fillstyle,所以我需要使用 plot

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

def ColorExtractor(cmap, colist):
    cmap = matplotlib.cm.get_cmap(cmap)
    rbga = cmap(colist)
    return rbga

colors = ColorExtractor('Blues', [3/3, 3/3, 2/3, 1/3])

fig, ax = plt.subplots()

x_data = np.array([0.975, 0.75, 0.525])

y_min  = np.array([3, 3, 2])
y_max  = np.array([4, 4, 3])

for xs, ys, cols, labs, flstl in zip([x_data, x_data], [y_min, y_max], [colors, colors], ['$x_{min}$', '$x_{max}$'], ['bottom', 'top']):
    ax.plot(xs, ys, 'k:')
    for x, y, col in zip(xs, ys, cols):
        ax.plot(x, y, color=col, marker='<', label=labs, fillstyle=flstl, markeredgecolor='k', linestyle='none', markersize=10)

ax.set_xlim(0.5, 1)
ax.set_ylim(1, 5)

ax.set_xlabel('$x$', fontsize=15)
ax.set_ylabel('$y$', fontsize=15)

handles, labels = ax.get_legend_handles_labels()
handles = [i[0] if isinstance(i, container.ErrorbarContainer) else i for i in handles]

by_label = dict(zip(labels, handles))

ax.legend(by_label.values(), by_label.keys(), loc=9, ncol=2, frameon=False)

leg = ax.get_legend()

for i in leg.legendHandles:
    i.set_color('k')
    i.set_markeredgecolor('k')
    #i.set_edgecolor('k')

plt.show()

除了最后一部分似乎没有做任何事情外,一切正常。因此,图例符号的颜色保持蓝色而不是黑色。我也希望 edgecolor 为黑色,但我已对其进行了评论,因为 AttributeError: 'Line2D' object has no attribute 'set_edgecolor' 会生成。

编辑:正如@Galunid 指出的那样,我可能应该使用 set_markeredgecolor 代替 set_edgecolor。但是,主要问题是我想将图例标记内的颜色更改为黑色。

enter image description here

我做错了什么?

1 个答案:

答案 0 :(得分:1)

如果您过早更改图例手柄,绘图内的颜色也会更改。因此,您需要制作手柄的副本,然后为这些副本着色。请注意,set_markerfacecolor() 更改标记的第一种颜色(示例代码中的 blue)。而 set_markerfacecoloralt() 会改变第二种颜色(white)。因此,您可能需要 set_markerfacecolor('black') 并保持其他颜色不变。

这是一个例子:

from copy import copy

handles, labels = ax.get_legend_handles_labels()
handles = [copy(i[0]) if isinstance(i, container.ErrorbarContainer) else copy(i) for i in handles]
for i in handles:
    i.set_markeredgecolor('black')
    i.set_markerfacecolor('crimson') # use 'black' to have that part black
    i.set_markerfacecoloralt('gold') # leave this line out in case the second color is already OK
by_label = dict(zip(labels, handles))
ax.legend(by_label.values(), by_label.keys(),  loc=9, ncol=2, frameon=False)

example plot