Python 带图例的Matplotlib散点图
我想创建一个Matplotlib散点图,用图例显示每个类的颜色。例如,我有一个Python 带图例的Matplotlib散点图,python,matplotlib,legend,Python,Matplotlib,Legend,我想创建一个Matplotlib散点图,用图例显示每个类的颜色。例如,我有一个x和y值的列表,以及一个类值的列表。x、y和classes列表中的每个元素对应于绘图中的一个点。我希望每个类都有自己的颜色,我已经编码过了,但是我希望这些类显示在一个图例中。我应该向legend()函数传递哪些参数来实现这一点 以下是我目前的代码: import matplotlib.pyplot as plt x = [1, 3, 4, 6, 7, 9] y = [0, 0, 5, 8, 8, 8] classes
x
和y
值的列表,以及一个类
值的列表。x
、y
和classes
列表中的每个元素对应于绘图中的一个点。我希望每个类都有自己的颜色,我已经编码过了,但是我希望这些类显示在一个图例中。我应该向legend()
函数传递哪些参数来实现这一点
以下是我目前的代码:
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()
首先,我有一种感觉,在宣布颜色时,你打算使用撇号,而不是反撇号 对于图例,您需要一些形状以及类。例如,下面为
class\u colors
中的每种颜色创建一个称为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)
还有第二种创建图例的方法,在这种方法中,可以使用单独的散点命令为一组点指定“标签”。下面给出了一个例子
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)
第一种方法是我个人使用的方法,第二种方法是我在查看matplotlib文档时发现的。因为图例覆盖了数据点,所以我移动了它们,并且可以找到图例的位置。如果有其他方法制作图例,我在文档中快速搜索了几次后就找不到了。有两种方法。其中一个可以为你所策划的每件事提供图例条目,另一个可以让你在图例中放入你想要的任何东西,从答案中大量窃取 第一种方法是:
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()
ax.legend()
函数有多种用途,第一种只是根据axes
对象中的行创建图例,第二种是手动控制条目,如下所述
您基本上需要为图例提供线句柄和相关标签
另一种方法是创建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()
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()
或者在这里,我们创建新的Line2D
对象,并将它们赋予图例
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()
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()
我还尝试使用
补丁
使该方法起作用,就像在matplotlib图例指南页面上一样,但似乎不起作用,所以我放弃了。在我的项目中,我还想创建一个空的散点图例。以下是我的解决方案:
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)
注意上面的“标签”、“散射点”。这在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()
如果您使用的是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())
此外,要用类名替换标签,
我们只需要scatter.legend_元素的句柄:
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)
您还可以使用带有内置彩色地图(来自matplotlib)的seaborn
您可以从中找到其他颜色映射。因此,在您的示例中,
recs
和标签是否具有相同的长度?难道没有一种方法可以使用我的示例中绘制的默认标记添加图例吗?奇怪的是,在散点图中创建图例的唯一方法是为所有点创建一个形状列表,而不是将所有点自动指定为相同的形状。第一个示例中的标签不正确,我的意思是使用类。我还发现了第二种方法,可以在我添加到答案的文档中创建一个图例,以及屏幕截图。我编写第二个代码块时假设来自不同类的数据是混合的。如果您知道您的数据是按类别和颜色分组的,您可以使用类a
的xc=x[0:2]
来显著简化第二个代码块。或者,如果您的数据最初是按类划分的,则不要将其合并到单个列表中,也不要跳过创建列表的需要。