legends - matplotlib title position
Detener matplotlib repetir etiquetas en la leyenda (5)
Aquí hay un ejemplo muy simplificado:
xvalues = [2,3,4,6]
for x in xvalues:
plt.axvline(x,color=''b'',label=''xvalues'')
plt.legend()
La leyenda ahora mostrará ''xvalues'' como una línea azul 4 veces en la leyenda. ¿Hay una forma más elegante de arreglar esto que la siguiente?
for i,x in enumerate(xvalues):
if not i:
plt.axvline(x,color=''b'',label=''xvalues'')
else:
plt.axvline(x,color=''b'')
Estos fragmentos de código no me funcionaron personalmente. Estaba tramando dos grupos diferentes en dos colores diferentes. La leyenda mostraría dos marcadores rojos y dos marcadores azules, cuando solo quería ver uno por color. Pegaré una versión simplificada de lo que funcionó para mí:
Importar declaraciones
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
Trazar datos
points_grp, = plt.plot(x[grp_idx], y[grp_idx], color=c.c[1], marker=m, ms=4, lw=0, label=leglab[1])
points_ctrl, = plt.plot(x[ctrl_idx], y[ctrl_idx], color=c.c[0], marker=m, ms=4, lw=0, label=leglab[0])
Añadir leyenda
points_dict = {points_grp: HandlerLine2D(numpoints=1),points_ctrl: HandlerLine2D(numpoints=1)}
leg = ax.legend(fontsize=12, loc=''upper left'', bbox_to_anchor=(1, 1.03),handler_map=points_dict)
No sé si esto puede considerarse "elegante", pero puede hacer que su etiqueta sea una variable que se establece en "_nolegend_"
después del primer uso:
my_label = "xvalues"
xvalues = [2,3,4,6]
for x in xvalues:
plt.axvline(x, color=''b'', label=my_label)
my_label = "_nolegend_"
plt.legend()
Esto se puede generalizar usando un diccionario de etiquetas si tiene que poner varias etiquetas:
my_labels = {"x1" : "x1values", "x2" : "x2values"}
x1values = [1, 3, 5]
x2values = [2, 4, 6]
for x in x1values:
plt.axvline(x, color=''b'', label=my_labels["x1"])
my_labels["x1"] = "_nolegend_"
for x in x2values:
plt.axvline(x, color=''r'', label=my_labels["x2"])
my_labels["x2"] = "_nolegend_"
plt.legend()
(Respuesta inspirada en https://.com/a/19386045/1878788 )
Según la respuesta https://.com/a/13589144/9132798 y https://.com/a/19386045/9132798 plt.gca().get_legend_handles_labels()[1]
da una lista de nombres, es Es posible verificar si la etiqueta ya está en la lista mientras está en el trazado del bucle ( label= name[i] if name[i] not in plt.gca().get_legend_handles_labels()[1] else ''''
). Para el ejemplo dado, esta solución se vería así:
import matplotlib.pyplot as plt
xvalues = [2,3,4,6]
for x in xvalues:
plt.axvline(x,color=''b'',/
label= ''xvalues'' if ''xvalues'' /
not in plt.gca().get_legend_handles_labels()[1] else '''')
plt.legend()
Que es mucho más corto que https://.com/a/13589144/9132798 y más flexible que https://.com/a/19386045/9132798 ya que podría usarse para cualquier tipo de bucle de cualquier función de trazado en el bucle de forma individual. Sin embargo, durante muchos ciclos probablemente sea más lento que https://.com/a/13589144/9132798 .
legend
toma como argumentos una lista de identificadores y etiquetas de ejes, por defecto a plt.gca().get_legend_handles_labels()
. Puede eliminar etiquetas duplicadas al llamar a legend
, por ejemplo:
from collections import OrderedDict
import matplotlib.pyplot as plt
handles, labels = plt.gca().get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
handles, labels = ax.get_legend_handles_labels()
handle_list, label_list = [], []
for handle, label in zip(handles, labels):
if label not in label_list:
handle_list.append(handle)
label_list.append(label)
plt.legend(handle_list, label_list)