python - pyplot - matplotlib xticks
Diagrama de dispersión de Matplotlib con leyenda (5)
Quiero crear un diagrama de dispersión Matplotlib, con una leyenda que muestre el color de cada clase.
Por ejemplo, tengo una lista de valores
y
, y una lista de valores de
classes
.
Cada elemento en las listas
x
,
y
y
classes
corresponde a un punto en la gráfica.
Quiero que cada clase tenga su propio color, que ya he codificado, pero luego quiero que las clases se muestren en una leyenda.
¿Qué parámetros paso a la función
legend()
para lograr esto?
Aquí está mi código hasta ahora:
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)
En mi proyecto, también quiero crear una leyenda de dispersión vacía. Aquí está mi solución:
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)
Tenga cuidado con la "etiqueta", "puntos de dispersión" arriba.
Esto se maneja fácilmente en el diagrama de dispersión de Seaborn. Aquí hay una implementación de la misma.
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()
Hay dos maneras de hacerlo. Uno de ellos te da entradas de leyenda para cada cosa que tramas, y el otro te permite poner lo que quieras en la leyenda, robando mucho de this respuesta.
Aquí está la primera forma:
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()
La función
ax.legend()
tiene más de un uso, la primera solo crea la leyenda basada en las líneas en el objeto
axes
, la segunda le permite controlar las entradas manualmente y se describe
here
.
Básicamente, debe darle a la leyenda los identificadores de línea y las etiquetas asociadas.
La otra forma le permite poner lo que quiera en la leyenda, creando los objetos y etiquetas del
Artist
, y pasándolos a la función
ax.legend()
.
Puede usar esto para poner solo algunas de sus líneas en la leyenda, o puede usarlo para poner lo que quiera en la leyenda.
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()
O aquí, creamos nuevos objetos
Line2D
y se los damos a la leyenda.
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()
También intenté que el método utilizara
patches
para funcionar, como en la página de guía de la leyenda matplotlib, pero no parecía funcionar, así que me di por vencido.
Primero, tengo la sensación de que querías usar apóstrofes, no retrocesos al declarar colores.
Para una leyenda, necesitas algunas formas, así como las clases.
Por ejemplo, lo siguiente crea una lista de rectángulos llamados
recs
para cada color en
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)
También puede usar círculos si lo desea, solo consulte la documentación de
matplotlib.patches
.
Hay una segunda forma de crear una leyenda, en la que se especifica la "Etiqueta" para un conjunto de puntos utilizando un comando de dispersión separado para cada conjunto.
Un ejemplo de esto se da a continuación.
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)
El primer método es el que he usado personalmente, el segundo que acabo de encontrar mirando la documentación de matplotlib. Como las leyendas cubrían los puntos de datos, las moví, y las ubicaciones de las leyendas se pueden encontrar here . Si hay otra forma de hacer una leyenda, no pude encontrarla después de algunas búsquedas rápidas en los documentos.
si está utilizando matplotlib versión 3.1.1 o superior, puede intentar:
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())
Además, para reemplazar etiquetas con nombres de clases, solo necesitamos identificadores de 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)