python - pyplot - matplotlib-subtramas con relación de aspecto fija
plot python 3 (3)
Tengo un problema con el trazado de múltiples subparcelas. Me gustaría establecer la relación de aspecto FÍSICO de las subtramas a un valor fijo. En mi ejemplo, tengo 12 subtramas (4 filas y 3 columnas) en una figura de paisaje A4. Allí, todas las subtramas están bien ubicadas en la figura completa, y para todas las subtramas, la altura es casi igual al ancho.
Pero si cambio el diseño de mi figura a retrato, las subparcelas se extienden verticalmente. Y esto es exactamente lo que no debería suceder. Me gustaría tener el mismo alto y ancho de las subtramas que en la figura del paisaje. ¿Existe la posibilidad de que la relación de aspecto de las subtramas permanezca igual?
Gracias de antemano, Peter
EDIT: he encontrado una solución. Pero esto solo funciona para ejes no logarítmicos ...
aspectratio=1.0
ratio_default=(ax.get_xlim()[1]-ax.get_xlim()[0])/(ax.get_ylim()[1]-ax.get_ylim()[0])
ax.set_aspect(ratio_default*aspectratio)
En realidad, lo que quieres es bastante simple ... Solo necesitas asegurarte de que el adjustable
esté configurado en ''box''
en tus ejes, y que tengas una relación de aspecto establecida para los ejes (cualquier cosa que no sea ''auto''
).
Puede hacer esto con el kwarg adjustable
cuando crea las subtramas. Alternativamente, puede hacer esto después de su creación llamando ax.set_adjustable(''box'')
, o llamando ax.set_aspect(aspect, adjustable=''box'')
(donde aspect es ''equal''
o un número).
Ahora, independientemente de cómo se cambie el tamaño de la figura, las subtramas mantendrán la misma relación de aspecto.
Por ejemplo:
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1, adjustable=''box'', aspect=0.3)
ax2 = fig.add_subplot(2,1,2)
ax1.plot(range(10))
ax2.plot(range(10))
plt.show()
Ahora, compara cómo la subtrama superior responde al cambio de tamaño, en comparación con la respuesta de la subtrama inferior:
La trama inicial
Cambia el tamaño a un diseño vertical:
Cambia el tamaño a un diseño horizontal:
En respuesta a la observación de que la solución no funciona para trazados logarítmicos en la edición de la pregunta original, debe adaptarse de la siguiente manera:
def fixed_aspect_ratio_loglog(ratio):
''''''
Set a fixed aspect ratio on matplotlib loglog plots
regardless of axis units
''''''
xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()
xrange = log(xvals[1])-log(xvals[0])
yrange = log(yvals[1])-log(yvals[0])
gca().set_aspect(ratio*(xrange/yrange), adjustable=''box'')
(La adaptación para las parcelas semilog debería ser ahora obvia)
Tu solución alternativa funciona para mí. Después de trazar los datos, invoco la siguiente función:
def fixed_aspect_ratio(ratio):
''''''
Set a fixed aspect ratio on matplotlib plots
regardless of axis units
''''''
xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()
xrange = xvals[1]-xvals[0]
yrange = yvals[1]-yvals[0]
gca().set_aspect(ratio*(xrange/yrange), adjustable=''box'')