简体   繁体   English

Matplotlib 散点图与图例

[英]Matplotlib scatter plot with legend

I want to create a Matplotlib scatter plot, with a legend showing the colour for each class.我想创建一个 Matplotlib 散点图,用图例显示每个类的颜色。 For example, I have a list of x and y values, and a list of classes values.例如,我有一个xy值列表,以及一个classes值列表。 Each element in the x , y and classes lists corresponds to one point in the plot. xyclasses列表中的每个元素对应于图中的一个点。 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?我将哪些参数传递给legend()函数来实现这一点?

Here is my code so far:到目前为止,这是我的代码:

import matplotlib.pyplot as plt
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)
plt.show()

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 recs for each colour in class_colours .例如,下面为class_colours每种颜色创建一个名为recs的矩形列表。

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)

第一个代码块的输出

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.下面给出了一个例子。

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.第一种方法是我个人使用的方法,第二种方法是我在查看 matplotlib 文档时发现的。 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.如果有另一种制作图例的方法,在文档中进行了几次快速搜索后,我无法找到它。

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())

结果1

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)

结果2

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 this answer.其中一个为您绘制的每个事物提供图例条目,另一个让您可以在图例中放入任何您想要的内容,从这个答案中大量窃取。

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 axes object, 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 Artist objects and labels, and passing them to the ax.legend() function.另一种方法允许您通过创建Artist对象和标签,并将它们传递给ax.legend()函数,在图例中放入任何您想要的ax.legend() 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.您可以使用它仅将某些行放入图例中,也可以使用它在图例中放入任何您想要的内容。

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 Line2D objects, 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 patches to work, as on the matplotlib legend guide page, but it didn't seem to work so i gave up.我还尝试使用patches来获得该方法,就像在 matplotlib 传奇指南页面上一样,但它似乎没有用,所以我放弃了。

This is easily handled in seaborn's scatterplot.这在 seaborn 的散点图中很容易处理。 Here's an implementation of it.这是它的一个实现。

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()

阴谋

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.注意上面的“标签”,“散点”。

You can also use seaborn with a built-in colormap (which comes from matplotlib).您还可以使用带有内置颜色图(来自 matplotlib)的 seaborn。

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']

sns.scatterplot(
    x=x, y=y, hue=classes, 
    legend="full", palette="rainbow"
)
# colormap used is "rainbow"

在此处输入图片说明

You can find other colormaps from Matplotlib colormap catalogue .您可以从Matplotlib 颜色图目录中找到其他颜色图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM