apretado_layout() no tiene en cuenta el título de la figura

Resuelto katrasnikj asked hace 13 años • 11 respuestas

Si agrego un subtítulo a mi figura de matplotlib, los títulos de la subtrama se superponen. ¿Alguien sabe cómo solucionarlo fácilmente? Probé la tight_layout()función, pero sólo empeora las cosas.

Ejemplo:

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.tight_layout()
plt.show()
katrasnikj avatar Nov 24 '11 03:11 katrasnikj
Aceptado

Puede ajustar la geometría de la subtrama en la misma tight_layoutllamada de la siguiente manera:

fig.tight_layout(rect=[0, 0.03, 1, 0.95])

Como se indica en la documentación ( https://matplotlib.org/users/tight_layout_guide.html ):

tight_layout()solo considera etiquetas de ticks, etiquetas de ejes y títulos. Por lo tanto, otros artistas pueden verse recortados y también superpuestos.

soupault avatar Jul 18 '2017 08:07 soupault

Puede ajustar manualmente el espaciado usando plt.subplots_adjust(top=0.85):

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.subplots_adjust(top=0.85)
plt.show()
unutbu avatar Nov 23 '2011 20:11 unutbu

Una cosa que podrías cambiar en tu código muy fácilmente es lo que fontsizeestás usando para los títulos. Sin embargo, voy a asumir que no solo quieres hacer eso.

Algunas alternativas al uso fig.subplots_adjust(top=0.85):

Por lo general, tight_layout()hace un buen trabajo al colocar todo en buenas ubicaciones para que no se superpongan. La razón tight_layout()no ayuda en este caso es porque tight_layout()no tiene en cuenta fig.suptitle(). Hay un problema abierto sobre esto en GitHub: https://github.com/matplotlib/matplotlib/issues/829 [cerrado en 2014 debido a que se requiere un administrador de geometría completo; trasladado a https://github.com/matplotlib/matplotlib /issues/1109 ].

Si lees el hilo, hay una solución a tu problema relacionado con GridSpec. La clave es dejar algo de espacio en la parte superior de la figura al llamar tight_layout, usando rectkwarg. Para su problema, el código se convierte en:

Usando GridSpec

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

f = np.random.random(100)
g = np.random.random(100)

fig = plt.figure(1)
gs1 = gridspec.GridSpec(1, 2)
ax_list = [fig.add_subplot(ss) for ss in gs1]

ax_list[0].plot(f)
ax_list[0].set_title('Very Long Title 1', fontsize=20)

ax_list[1].plot(g)
ax_list[1].set_title('Very Long Title 2', fontsize=20)

fig.suptitle('Long Suptitle', fontsize=24)    

gs1.tight_layout(fig, rect=[0, 0.03, 1, 0.95])  

plt.show()

El resultado:

usando gridspec

Tal vez GridSpecsea un poco excesivo para usted, o su verdadero problema involucrará muchas más tramas secundarias en un lienzo mucho más grande u otras complicaciones. Un truco simple es simplemente usar annotate()y bloquear las coordenadas para 'figure fraction'imitar un archivo suptitle. Sin embargo, es posible que deba realizar algunos ajustes más precisos una vez que observe el resultado. Tenga en cuenta que esta segunda solución no utiliza tight_layout().

Solución más sencilla (aunque es posible que sea necesario perfeccionarla)

fig = plt.figure(2)

ax1 = plt.subplot(121)
ax1.plot(f)
ax1.set_title('Very Long Title 1', fontsize=20)

ax2 = plt.subplot(122)
ax2.plot(g)
ax2.set_title('Very Long Title 2', fontsize=20)

# fig.suptitle('Long Suptitle', fontsize=24)
# Instead, do a hack by annotating the first axes with the desired 
# string and set the positioning to 'figure fraction'.
fig.get_axes()[0].annotate('Long Suptitle', (0.5, 0.95), 
                            xycoords='figure fraction', ha='center', 
                            fontsize=24
                            )
plt.show()

El resultado:

simple

[Usando Python2.7.3 (64 bits) y matplotlib1.2.0]

aseagram avatar Oct 28 '2013 04:10 aseagram