font python matplotlib

font - subplot python



¿Cómo hago una sola leyenda para muchas subtramas con matplotlib? (6)

Esta respuesta es un complemento de @ Evert en la posición de leyenda.

Mi primer intento en la solución de @Evert fracasó debido a superposiciones de la leyenda y el título de la subtrama.

De hecho, las superposiciones son causadas por fig.tight_layout() , que cambia el diseño de las subtramas sin tener en cuenta la leyenda de la figura. Sin embargo, fig.tight_layout() es necesario.

Para evitar las superposiciones, podemos decir a fig.tight_layout() que deje espacios para la leyenda de la figura mediante fig.tight_layout(rect=(0,0,1,0.9)) .

Descripción de los parámetros tight_layout () .

Estoy trazando el mismo tipo de información, pero para diferentes países, con múltiples subtramas con matplotlib. Es decir, tengo 9 tramas en una cuadrícula de 3x3, todas con lo mismo para las líneas (por supuesto, diferentes valores por línea).

Sin embargo, no he descubierto cómo poner una sola leyenda (ya que las 9 subparcelas tienen las mismas líneas) en la figura solo una vez.

¿Cómo puedo hacer eso?


Para el posicionamiento automático de una única leyenda en una figure con muchos ejes, como los obtenidos con subplots() , la siguiente solución funciona muy bien:

plt.legend( lines, labels, loc = ''lower center'', bbox_to_anchor = (0,-0.1,1,1), bbox_transform = plt.gcf().transFigure )

Con bbox_to_anchor y bbox_transform=plt.gcf().transFigure está definiendo un nuevo cuadro delimitador del tamaño de su figure para que sea una referencia para loc . El uso de (0,-0.1,1,1) mueve este buzón ligeramente hacia abajo para evitar que la leyenda se coloque sobre otros artistas.

OBS: use esta solución DESPUÉS de usar fig.set_size_inches() y ANTES de usar fig.tight_layout()


Si bien es bastante tarde para el juego, daré otra solución aquí, ya que este sigue siendo uno de los primeros enlaces en aparecer en Google. Usando matplotlib 2.2.2, esto se puede lograr usando la función gridspec. En el siguiente ejemplo, el objetivo es tener cuatro subparcelas dispuestas en una forma 2x2 con la leyenda que se muestra en la parte inferior. Se crea un eje ''falso'' en la parte inferior para colocar la leyenda en un punto fijo. El eje "falso" se apaga, por lo que solo se muestra la leyenda. Resultado: https://i.stack.imgur.com/5LUWM.png .

import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec #Gridspec demo fig = plt.figure() fig.set_size_inches(8,9) fig.set_dpi(100) rows = 17 #the larger the number here, the smaller the spacing around the legend start1 = 0 end1 = int((rows-1)/2) start2 = end1 end2 = int(rows-1) gspec = gridspec.GridSpec(ncols=4, nrows=rows) axes = [] axes.append(fig.add_subplot(gspec[start1:end1,0:2])) axes.append(fig.add_subplot(gspec[start2:end2,0:2])) axes.append(fig.add_subplot(gspec[start1:end1,2:4])) axes.append(fig.add_subplot(gspec[start2:end2,2:4])) axes.append(fig.add_subplot(gspec[end2,0:4])) line, = axes[0].plot([0,1],[0,1],''b'') #add some data axes[-1].legend((line,),(''Test'',),loc=''center'') #create legend on bottommost axis axes[-1].set_axis_off() #don''t show bottommost axis fig.tight_layout() plt.show()


Solo tienes que pedir la leyenda una vez, fuera de tu loop.

Por ejemplo, en este caso tengo 4 subtramas, con las mismas líneas, y una sola leyenda.

from matplotlib.pyplot import * ficheiros = [''120318.nc'', ''120319.nc'', ''120320.nc'', ''120321.nc''] fig = figure() fig.suptitle(''concentration profile analysis'') for a in range(len(ficheiros)): # dados is here defined level = dados.variables[''level''][:] ax = fig.add_subplot(2,2,a+1) xticks(range(8), [''0h'',''3h'',''6h'',''9h'',''12h'',''15h'',''18h'',''21h'']) ax.set_xlabel(''time (hours)'') ax.set_ylabel(''CONC ($/mu g. m^{-3}$)'') for index in range(len(level)): conc = dados.variables[''CONC''][4:12,index] * 1e9 ax.plot(conc,label=str(level[index])+''m'') dados.close() ax.legend(bbox_to_anchor=(1.05, 0), loc=''lower left'', borderaxespad=0.) # it will place the legend on the outer right-hand side of the last axes show()


También hay una buena función get_legend_handles_labels() que puede invocar en el último eje (si itera sobre ellos) que recolectaría todo lo que necesita de label= arguments:

handles, labels = ax.get_legend_handles_labels() fig.legend(handles, labels, loc=''upper center'')