Estoy familiarizado con las siguientes preguntas:
Matplotlib savefig con una leyenda fuera de la trama
Cómo sacar la leyenda de la trama
Parece que las respuestas en estas preguntas tienen el lujo de poder jugar con la reducción exacta del eje para que la leyenda encaje.
Sin embargo, la reducción de los ejes no es una solución ideal porque hace que los datos sean más pequeños y que en realidad sea más difícil de interpretar; particularmente cuando es complejo y hay muchas cosas sucediendo ... por lo tanto, necesita una gran leyenda
El ejemplo de una leyenda compleja en la documentación demuestra la necesidad de esto porque la leyenda en su diagrama en realidad oscurece por completo múltiples puntos de datos.
http://matplotlib.sourceforge.net/users/legend_guide.html#legend-of-complex-plots
Lo que me gustaría poder hacer es expandir dinámicamente el tamaño del cuadro de figura para acomodar la leyenda de la figura en expansión.
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')
lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,0))
ax.grid('on')
Observe cómo la etiqueta final 'Inverse tan' está realmente fuera del cuadro de la figura (y se ve muy mal, ¡no es la calidad de publicación!)
Finalmente, me han dicho que este es un comportamiento normal en R y LaTeX, así que estoy un poco confundido por qué esto es tan difícil en Python ... ¿Hay alguna razón histórica? ¿Matlab es igualmente pobre en este asunto?
Tengo la versión (solo un poco) más larga de este código en pastebin http://pastebin.com/grVjc007
fuente
tight_layout()
debe cambiarse para tener en cuenta las leyendas.Respuestas:
Lo siento EMS, pero en realidad acabo de recibir otra respuesta de la lista de correo matplotlib (Gracias a Benjamin Root).
El código que estoy buscando está ajustando la llamada savefig a:
Esto es aparentemente similar a llamar a tight_layout, pero en su lugar, permite que savefig considere artistas adicionales en el cálculo. De hecho, esto redimensionó el cuadro de la figura como se desea.
Esto produce:
[editar] La intención de esta pregunta era evitar por completo el uso de ubicaciones de coordenadas arbitrarias de texto arbitrario como era la solución tradicional a estos problemas. A pesar de esto, numerosas ediciones han insistido recientemente en incluirlas, a menudo en formas que llevaron al código a generar un error. Ahora he solucionado los problemas y he ordenado el texto arbitrario para mostrar cómo estos también se consideran dentro del algoritmo bbox_extra_artists.
fuente
plt.show()
. ¿Alguna solución para eso?fig.legend()
método , realmente extraño.Agregado: Encontré algo que debería hacer el truco de inmediato, pero el resto del código a continuación también ofrece una alternativa.
Use la
subplots_adjust()
función para mover la parte inferior de la subtrama hacia arriba:Luego juegue con el desplazamiento en la
bbox_to_anchor
parte de leyenda del comando de leyenda, para obtener el cuadro de leyenda donde lo desee. Alguna combinación de configurarfigsize
y usar elsubplots_adjust(bottom=...)
debería producir un gráfico de calidad para usted.Alternativa: simplemente cambié la línea:
a:
y cambiado
a
y aparece bien en mi pantalla (un monitor CRT de 24 pulgadas).
Aquí
figsize=(M,N)
establece que la ventana de la figura sea M pulgadas por N pulgadas. Solo juega con esto hasta que te parezca adecuado. Conviértalo a un formato de imagen más escalable y use GIMP para editar si es necesario, o simplemente recorte con laviewport
opción LaTeX cuando incluya gráficos.fuente
Aquí hay otra solución muy manual. Puede definir el tamaño del eje y los rellenos se consideran en consecuencia (incluidas la leyenda y las marcas de verificación). Espero que sea de utilidad para alguien.
Ejemplo (¡el tamaño de los ejes es el mismo!):
Código:
fuente
plt.draw()
aax.figure.canvas.draw()
. No estoy seguro de por qué, pero antes de este cambio, el tamaño de la leyenda no se actualizaba.fig.set_size_inches(widthTot,heightTot)
afig.set_size_inches(widthTot,heightTot, forward=True)
.