tiempo real matrices graficos graficas graficar ejes coordenadas python matplotlib plot legend

python - real - pyplot combina varias etiquetas de líneas en la leyenda



matplotlib python 3 (4)

Tengo datos que dan como resultado el trazado de múltiples líneas, quiero dar a estas líneas una sola etiqueta en mi leyenda. Creo que esto se puede demostrar mejor usando el siguiente ejemplo,

a = np.array([[ 3.57, 1.76, 7.42, 6.52], [ 1.57, 1.2 , 3.02, 6.88], [ 2.23, 4.86, 5.12, 2.81], [ 4.48, 1.38, 2.14, 0.86], [ 6.68, 1.72, 8.56, 3.23]]) plt.plot(a[:,::2].T, a[:, 1::2].T, ''r'', label=''data_a'') plt.legend(loc=''best'')

Como se puede ver en Out [23] la trama resultó en 5 líneas distintas. La trama resultante se ve así

¿Hay alguna manera de que pueda decir el método de trazado para evitar etiquetas múltiples? No deseo utilizar la leyenda personalizada (donde especifica la etiqueta y la forma de la línea, todo a la vez) tanto como pueda.


Haría una pequeña función de ayudante personalmente, si planeaba hacerlo a menudo;

from matplotlib import pyplot import numpy a = numpy.array([[ 3.57, 1.76, 7.42, 6.52], [ 1.57, 1.2 , 3.02, 6.88], [ 2.23, 4.86, 5.12, 2.81], [ 4.48, 1.38, 2.14, 0.86], [ 6.68, 1.72, 8.56, 3.23]]) def plotCollection(ax, xs, ys, *args, **kwargs): ax.plot(xs,ys, *args, **kwargs) if "label" in kwargs.keys(): #remove duplicates handles, labels = pyplot.gca().get_legend_handles_labels() newLabels, newHandles = [], [] for handle, label in zip(handles, labels): if label not in newLabels: newLabels.append(label) newHandles.append(handle) pyplot.legend(newHandles, newLabels) ax = pyplot.subplot(1,1,1) plotCollection(ax, a[:,::2].T, a[:, 1::2].T, ''r'', label=''data_a'') plotCollection(ax, a[:,1::2].T, a[:, ::2].T, ''b'', label=''data_b'') pyplot.show()

Una forma más fácil (y más clara de IMO) de eliminar duplicados (que los que tiene) de los handles y labels de la leyenda es esta:

handles, labels = pyplot.gca().get_legend_handles_labels() newLabels, newHandles = [], [] for handle, label in zip(handles, labels): if label not in newLabels: newLabels.append(label) newHandles.append(handle) pyplot.legend(newHandles, newLabels)


Numpy solución basada en la respuesta de voluntad anterior.

import numpy as np import matplotlib.pylab as plt a = np.array([[3.57, 1.76, 7.42, 6.52], [1.57, 1.20, 3.02, 6.88], [2.23, 4.86, 5.12, 2.81], [4.48, 1.38, 2.14, 0.86], [6.68, 1.72, 8.56, 3.23]]) plt.plot(a[:,::2].T, a[:, 1::2].T, ''r'', label=''data_a'') handles, labels = plt.gca().get_legend_handles_labels()

Suponiendo que las etiquetas iguales tengan los mismos identificadores, obtenga etiquetas únicas y sus respectivos índices, que corresponden a los índices de control.

labels, ids = np.unique(labels, return_index=True) handles = [handles[i] for i in ids] plt.legend(handles, labels, loc=''best'') plt.show()


Matplotlib le ofrece una interfaz agradable para colecciones de líneas, LineCollection . El código es directo

import numpy import matplotlib.pyplot as plt from matplotlib.collections import LineCollection a = numpy.array([[ 3.57, 1.76, 7.42, 6.52], [ 1.57, 1.2 , 3.02, 6.88], [ 2.23, 4.86, 5.12, 2.81], [ 4.48, 1.38, 2.14, 0.86], [ 6.68, 1.72, 8.56, 3.23]]) xs = a[:,::2] ys = a[:, 1::2] lines = LineCollection([list(zip(x,y)) for x,y in zip(xs, ys)], label=''data_a'') f, ax = plt.subplots(1, 1) ax.add_collection(lines) ax.legend() ax.set_xlim([xs.min(), xs.max()]) # have to set manually ax.set_ylim([ys.min(), ys.max()]) plt.show()

Esto resulta en el resultado a continuación:


Entonces, usando la sugerencia de Will y otra pregunta aquí , dejo mi remedio aquí

handles, labels = plt.gca().get_legend_handles_labels() i =1 while i<len(labels): if labels[i] in labels[:i]: del(labels[i]) del(handles[i]) else: i +=1 plt.legend(handles, labels)

Y la nueva trama parece,