Python Matplotlib 散点图与图例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26558816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Matplotlib scatter plot with legend
提问by Karnivaurus
I want to create a Matplotlib scatter plot, with a legend showing the colour for each class. For example, I have a list of xand yvalues, and a list of classesvalues. Each element in the x, yand classeslists corresponds to one point in the plot. I want each class to have its own colour, which I have already coded, but then I want the classes to be displayed in a legend. What paramaters do I pass to the legend()function to achieve this?
我想创建一个 Matplotlib 散点图,用图例显示每个类的颜色。例如,我有一个x和y值列表和一个classes值列表。x、y和classes列表中的每个元素对应于图中的一个点。我希望每个类都有自己的颜色,我已经编码了,但是我希望这些类显示在图例中。我传递给legend()函数的参数是什么来实现这一点?
Here is my code so far:
到目前为止,这是我的代码:
x = [1, 3, 4, 6, 7, 9]
y = [0, 0, 5, 8, 8, 8]
classes = ['A', 'A', 'B', 'C', 'C', 'C']
colours = ['r', 'r', 'b', 'g', 'g', 'g']
plt.scatter(x, y, c=colours)
采纳答案by TheSchwa
First, I have a feeling you meant to use apostrophes, not backticks when declaring colours.
首先,我有一种感觉,您打算在声明颜色时使用撇号,而不是反引号。
For a legend you need some shapes as well as the classes. For example, the following creates a list of rectangles called recsfor each colour in class_colours.
对于图例,您需要一些形状和类。例如,下面创建了一个矩形列表,recs为 中的每种颜色调用class_colours。
import matplotlib.patches as mpatches
classes = ['A','B','C']
class_colours = ['r','b','g']
recs = []
for i in range(0,len(class_colours)):
recs.append(mpatches.Rectangle((0,0),1,1,fc=class_colours[i]))
plt.legend(recs,classes,loc=4)


You could use circles too if you wanted, just check out the matplotlib.patchesdocumentation. There is a second way of creating a legend, in which you specify the "Label" for a set of points using a separate scatter command for each set. An example of this is given below.
如果需要,您也可以使用圆圈,只需查看matplotlib.patches文档即可。还有第二种创建图例的方法,在该方法中,您可以为一组点使用单独的散点命令为每个点指定“标签”。下面给出了一个例子。
classes = ['A','A','B','C','C','C']
colours = ['r','r','b','g','g','g']
for (i,cla) in enumerate(set(classes)):
xc = [p for (j,p) in enumerate(x) if classes[j]==cla]
yc = [p for (j,p) in enumerate(y) if classes[j]==cla]
cols = [c for (j,c) in enumerate(colours) if classes[j]==cla]
plt.scatter(xc,yc,c=cols,label=cla)
plt.legend(loc=4)


The first method is the one I've personally used, the second I just found looking at the matplotlib documentation. Since the legends were covering datapoints I moved them, and the locations for legends can be found here. If there's another way to make a legend, I wasn't able to find it after a few quick searches in the docs.
第一种方法是我个人使用的方法,第二种方法是我在查看 matplotlib 文档时发现的。由于图例覆盖了数据点,我移动了它们,图例的位置可以在这里找到。如果有另一种制作图例的方法,在文档中进行了几次快速搜索后,我无法找到它。
回答by will
There are two ways to do it. One of them gives you legend entries for each thing you plot, and the other one lets you put whatever you want in the legend, stealing heavily from thisanswer.
有两种方法可以做到。其中一个为您绘制的每个事物提供图例条目,另一个让您可以在图例中放入任何您想要的内容,从这个答案中大量窃取。
Here's the first way:
这是第一种方法:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-1,1,100)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
#Plot something
ax.plot(x,x, color='red', ls="-", label="$P_1(x)$")
ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$")
ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$")
ax.legend()
plt.show()


The ax.legend()function has more than one use, the first just creates the legend based on the lines in axesobject, the second allwos you to control the entries manually, and is described here.
该ax.legend()功能有多个用途,第一个只是根据axes对象中的线条创建图例,第二个您可以手动控制条目,并在此处进行描述。
You basically need to give the legend the line handles, and associated labels.
您基本上需要为图例提供线句柄和相关标签。
The other way allows you to put whatever you want in the legend, by creating the Artistobjects and labels, and passing them to the ax.legend()function. You can either use this to only put some of your lines in the legend, or you can use it to put whatever you want in the legend.
另一种方式允许您通过创建Artist对象和标签并将它们传递给ax.legend()函数,将任何您想要的内容放入图例中。您可以使用它仅将某些行放入图例中,也可以使用它在图例中放入任何您想要的内容。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-1,1,100)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
#Plot something
p1, = ax.plot(x,x, color='red', ls="-", label="$P_1(x)$")
p2, = ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$")
p3, = ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$")
#Create legend from custom artist/label lists
ax.legend([p1,p2], ["$P_1(x)$", "$P_2(x)$"])
plt.show()


Or here, we create new Line2Dobjects, and give them to the legend.
或者在这里,我们创建新Line2D对象,并将它们赋予图例。
import matplotlib.pyplot as pltit|delete|flag
import numpy as np
import matplotlib.patches as mpatches
x = np.linspace(-1,1,100)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
#Plot something
p1, = ax.plot(x,x, color='red', ls="-", label="$P_1(x)$")
p2, = ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$")
p3, = ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$")
fakeLine1 = plt.Line2D([0,0],[0,1], color='Orange', marker='o', linestyle='-')
fakeLine2 = plt.Line2D([0,0],[0,1], color='Purple', marker='^', linestyle='')
fakeLine3 = plt.Line2D([0,0],[0,1], color='LightBlue', marker='*', linestyle=':')
#Create legend from custom artist/label lists
ax.legend([fakeLine1,fakeLine2,fakeLine3], ["label 1", "label 2", "label 3"])
plt.show()


I also tried to get the method using patchesto work, as on the matplotlib legend guide page, but it didn't seem to work so i gave up.
我还尝试使该方法patches起作用,就像在 matplotlib 传奇指南页面上一样,但它似乎不起作用,所以我放弃了。
回答by bazingaedward
In my project,i also want to create an empty scatter legend.Here is my solution:
在我的项目中,我还想创建一个空的散布图例。这是我的解决方案:
from mpl_toolkits.basemap import Basemap
#use the scatter function from matplotlib.basemap
#you can use pyplot or other else.
select = plt.scatter([], [],s=200,marker='o',linewidths='3',edgecolor='#0000ff',facecolors='none',label=u'监测站点')
plt.legend(handles=[select],scatterpoints=1)
Take care of "label","scatterpoints"in above.
注意上面的“标签”,“散点”。
回答by Divyanshu Srivastava
This is easily handled in seaborn's scatterplot. Here's an implementation of it.
这在 seaborn 的散点图中很容易处理。这是它的一个实现。
import matplotlib.pyplot as plt
import seaborn as sns
x = [1, 3, 4, 6, 7, 9]
y = [0, 0, 5, 8, 8, 8]
classes = ['A', 'A', 'B', 'C', 'C', 'C']
colours = ['r', 'r', 'b', 'g', 'g', 'g']
sns.scatterplot(x=x, y=y, hue=classes)
plt.show()


回答by OliverQ
if you are using matplotlib version 3.1.1 or above, you can try:
如果您使用的是 matplotlib 3.1.1 或更高版本,您可以尝试:
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
x = [1, 3, 4, 6, 7, 9]
y = [0, 0, 5, 8, 8, 8]
classes = ['A', 'A', 'B', 'C', 'C', 'C']
values = [0, 0, 1, 2, 2, 2]
colours = ListedColormap(['r','b','g'])
scatter = plt.scatter(x, y,c=values, cmap=colours)
plt.legend(*scatter.legend_elements())
Furthermore, to replace labels with classes names, we only need handles from scatter.legend_elements:
此外,为了用类名替换标签,我们只需要来自 scatter.legend_elements 的句柄:
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
x = [1, 3, 4, 6, 7, 9]
y = [0, 0, 5, 8, 8, 8]
classes = ['A', 'B', 'C']
values = [0, 0, 1, 2, 2, 2]
colours = ListedColormap(['r','b','g'])
scatter = plt.scatter(x, y,c=values, cmap=colours)
plt.legend(handles=scatter.legend_elements()[0], labels=classes)

