boost el ancho de línea de las líneas de leyenda en matplotlib

Sé que si cambio el ancho de línea de una línea, eso se actualiza automáticamente en la leyenda. Sin embargo, me gustaría simplemente cambiar el ancho de línea de leyenda sin afectar la ttwig.

Aquí hay un ejemplo simple de cómo hacerlo:

import numpy as np import matplotlib.pyplot as plt # make some data x = np.linspace(0, 2*np.pi) y1 = np.sin(x) y2 = np.cos(x) # plot sin(x) and cos(x) p1 = plt.plot(x, y1, 'b-', linewidth=1.0) p2 = plt.plot(x, y2, 'r-', linewidth=1.0) # make a legend for both plots leg = plt.legend([p1, p2], ['sin(x)', 'cos(x)'], loc=1) # set the linewidth of each legend object for legobj in leg.legendHandles: legobj.set_linewidth(2.0) plt.show() 

El método de @Brendan Wood utiliza la api proporcionada por pyplot . En matplotlib, se prefiere el estilo orientado a objetos usando ejes . Lo siguiente es cómo puedes lograr esto usando el método de axes .

 import numpy as np import matplotlib.pyplot as plt # make some data x = np.linspace(0, 2*np.pi) y1 = np.sin(x) y2 = np.cos(x) fig, ax = plt.subplots() ax.plot(x, y1, linewidth=1.0, label='sin(x)') ax.plot(x, y2, linewidth=1.0, label='cos(x)') leg = ax.legend() for line in leg.get_lines(): line.set_linewidth(4.0) plt.show() 

La plot producida se muestra a continuación, introduzca la descripción de la imagen aquí

Si desea cambiar todas las líneas en un trazado, puede ser útil definir su propio controlador de leyenda:

 import matplotlib.pyplot as plt from matplotlib import legend_handler from matplotlib.lines import Line2D import numpy as np class MyHandlerLine2D(legend_handler.HandlerLine2D): def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) ydata = ((height-ydescent)/2.)*np.ones(xdata.shape, float) legline = Line2D(xdata, ydata) self.update_prop(legline, orig_handle, legend) #legline.update_from(orig_handle) #legend._set_artist_props(legline) # after update #legline.set_clip_box(None) #legline.set_clip_path(None) legline.set_drawstyle('default') legline.set_marker("") legline.set_linewidth(10) legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)]) self.update_prop(legline_marker, orig_handle, legend) #legline_marker.update_from(orig_handle) #legend._set_artist_props(legline_marker) #legline_marker.set_clip_box(None) #legline_marker.set_clip_path(None) legline_marker.set_linestyle('None') if legend.markerscale != 1: newsz = legline_marker.get_markersize()*legend.markerscale legline_marker.set_markersize(newsz) # we don't want to add this to the return list because # the texts and handles are assumed to be in one-to-one # correpondence. legline._legmarker = legline_marker return [legline, legline_marker] plt.plot( [0, 1], [0, 1], '-r', lw=1, label='Line' ) plt.legend(handler_map={Line2D:MyHandlerLine2D()}) plt.show() 

Por defecto, la leyenda contiene las líneas mismas. Por lo tanto, cambiar el ancho de línea de las líneas en el canvas también cambiará las líneas en la leyenda (y viceversa, ya que son esencialmente el mismo objeto).

Una posible solución es utilizar una copia del artista del canvas y cambiar solo el ancho de línea de la copia.

 import numpy as np import matplotlib.pyplot as plt import copy x = np.linspace(0, 2*np.pi) y1 = np.sin(x) y2 = np.cos(x) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, y1, c='b', label='y1',linewidth=1.0) ax.plot(x, y2, c='r', label='y2') # obtain the handles and labels from the figure handles, labels = ax.get_legend_handles_labels() # copy the handles handles = [copy.copy(ha) for ha in handles ] # set the linewidths to the copies [ha.set_linewidth(7) for ha in handles ] # put the copies into the legend leg = plt.legend(handles=handles, labels=labels) plt.savefig('leg_example') plt.show() 

introduzca la descripción de la imagen aquí

Una opción diferente sería utilizar un handler_map y una función de actualización. Esto es de alguna manera automático, especificando que el mapa del manejador automáticamente haría que cualquier línea en la leyenda tenga 7 puntos de ancho.

 import numpy as np import matplotlib.pyplot as plt from matplotlib.legend_handler import HandlerLine2D x = np.linspace(0, 2*np.pi) y1 = np.sin(x) y2 = np.cos(x) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, y1, c='b', label='y1',linewidth=1.0) ax.plot(x, y2, c='r', label='y2') linewidth=7 def update(handle, orig): handle.update_from(orig) handle.set_linewidth(7) plt.legend(handler_map={plt.Line2D : HandlerLine2D(update_func=update)}) plt.show() 

El resultado es el mismo que el de arriba.