Python 图例中的颜色与图形颜色不匹配

Python 图例中的颜色与图形颜色不匹配,python,matplotlib,graph,Python,Matplotlib,Graph,我试图制作自定义图例,仅显示绘制的部分线条。但是,图例中的颜色并不总是与打印线的颜色匹配。在示例中,图例1和图例2可以,但图例3应显示蓝色和绿色,而不是蓝色和橙色。请参阅所附图片。我怎样才能解决这个问题 这是一个我用来生成图像的mwe,但请注意,在实际程序中,plot函数不能直接访问,也不能从其他文件加载。此外,不应修改plot函数,因为它也用于其他程序中 import matplotlib.pyplot as plt import numpy as np def my_plot_funct

我试图制作自定义图例,仅显示绘制的部分线条。但是,图例中的颜色并不总是与打印线的颜色匹配。在示例中,图例1和图例2可以,但图例3应显示蓝色和绿色,而不是蓝色和橙色。请参阅所附图片。我怎样才能解决这个问题

这是一个我用来生成图像的mwe,但请注意,在实际程序中,plot函数不能直接访问,也不能从其他文件加载。此外,不应修改plot函数,因为它也用于其他程序中

import matplotlib.pyplot as plt
import numpy as np

def my_plot_function(x,y,ax):
    #do complicated stuff here, manipulating y for example
    ax.plot(x,y)

x = np.linspace(0,1,100)
fig = plt.figure()
ax = fig.add_subplot(111)

my_plot_function(x, x, ax)
my_plot_function(x, x**2, ax)
my_plot_function(x, x**3, ax)
my_plot_function(x, x**4, ax)

lines = ax.get_lines()
print(lines[0])
print(lines[1])
print(lines[2])
print(lines[3])

fig.legend(lines, labels=range(4), loc=1, title="legend 1")
fig.legend([lines[0],lines[1]], labels=["0","1"], loc=2, title="legend 2")
fig.legend([lines[0],lines[2]], labels=["0","2"], loc=3, title="legend 3")
plt.show()
编辑:

为了澄清我的要求:绘图需要通过
my_plot_函数
完成,该函数在单独的文件中定义,不能修改。因此,我无法向它传递其他关键字,例如
标签

当我运行您的代码时,我从
legend.py
收到一条警告:

UserWarning: You have mixed positional and keyword arguments, some input may be discarded.
  warnings.warn("You have mixed positional and keyword "...
这可能就是它不起作用的原因。您需要在图例调用中添加
处理程序。即

fig.legend(handlers=[lines[0],lines[1]],...
顺便说一下,在创建绘图时指定标签是一种很好的做法

ax.plot(x, y, label='some label')
然后你可以打电话

handles, labels = ax.get_legend_handles_labels()
在传说中使用它们,就像这样

fig.legend(handles=(handles[0],handles[2]), labels=(labels[0],labels[2]),...)

使用
句柄
关键字参数:

fig.legend(handles=lines, labels=range(4), loc=1, title="legend 1")
fig.legend(handles=[lines[0],lines[1]], labels=["0","1"], loc=2, title="legend 2")
fig.legend(handles=[lines[0],lines[2]], labels=["0","2"], loc=3, title="legend 3")

当查看figure.legend的文档时,我们可以看到标签必须与句柄一起使用(反之亦然)。必须同时放置句柄和标签,或者不放置任何句柄和标签

这很有效

fig.legend(lines, range(4), loc=1, title="legend 1")
fig.legend((lines[0],lines[1]), ("0","1"), loc=2, title="legend 2")
fig.legend((lines[0],lines[2]), ("0","2"), loc=3, title="legend 3")
这是有效的

fig.legend(handles=lines, labels=range(4), loc=1, title="legend 1")
fig.legend(handles=(lines[0],lines[1]), labels=("0","1"), loc=2, title="legend 2")
fig.legend(handles=(lines[0],lines[2]), labels=("0","2"), loc=3, title="legend 3")

我会以稍微不同的方式处理这个问题。在像您这样的情况下,我始终建议在使用
标签
关键字打印时传递图例条目。然后,要使用选定的图例,可以使用
获取图例句柄\u标签()
,然后将所需项目传递到
图图例()。您不必指定
句柄
标签
参数。但是如果您指定了一个(就像您为
标签
所做的那样),您还应该指定另一个,否则您将收到警告

import matplotlib.pyplot as plt
import numpy as np

def plot(x,y,ax):
    ax.plot(x,y)

x = np.linspace(0,1,100)
fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(x, x, label='0')
ax.plot(x, x**2, label='1')
ax.plot(x, x**3, label='2')
ax.plot(x, x**4, label='3')
ax.legend(loc=1, title='legend 1')

h, l = ax.get_legend_handles_labels()

fig.legend([h[0],h[1]], [l[0], l[1]], loc=2, title="legend 2")
fig.legend([h[0],h[2]], [l[0], l[2]], loc=3, title="legend 3")
plt.show() 

下面是另一种回答@GBOFI注释的方法,您不使用全局图例提取值

x = np.linspace(0,1,100)
fig = plt.figure()
ax = fig.add_subplot(111)

l0, = ax.plot(x, x, label='0')
l1, = ax.plot(x, x**2, label='1')
l2, = ax.plot(x, x**3, label='2')
l3, = ax.plot(x, x**4, label='3')

fig.legend([l0, l1], [l0.get_label(), l1.get_label()], loc=2, title="legend 2")
fig.legend([l0, l2], [l0.get_label(), l2.get_label()], loc=3, title="legend 3")
plt.show() 

我投了更高的票,但是。。。假设我不想要一个全局图例(用于获取句柄和标签的图例),但只需要两个图例,分别是第0行、第1行和第2行、第3行(我假设的用例,不重复信息,比OP的更真实)。还有可能使用类似的方法吗?@GBOFI:如果我没弄错的话,一种方法是用
ax.legend()替换第一个或第二个
fig.legend()
。。这将用4个入口替换轴级全局图例。因此,您使用它只是提取句柄和图例,然后覆盖it@gboffi当前位置我添加了一个备选答案。如果它能解决你的问题,请告诉我。谢谢你详尽的回答,但它并不能完全解决我的问题。我按问题进行编辑,以更清楚地说明绘图需要通过
my\u plot\u函数来完成,我无法修改该函数。因此,我不能直接使用
ax.plot
,也不能传递标签。不管怎样,我喜欢
.get\u label()
方法,因为我已经有了一个行句柄。谢谢,我习惯于两者兼而有之。我们应该改变这种习惯,更仔细地阅读警告。