Subplots de diferentes tamaños de Matplotlib

238

Necesito agregar dos subtramas a una figura. Una subtrama debe ser aproximadamente tres veces más ancha que la segunda (misma altura). Logré esto usando GridSpecy el colspanargumento, pero me gustaría hacerlo usando figurepara poder guardar en PDF. Puedo ajustar la primera figura usando el figsizeargumento en el constructor, pero ¿cómo cambio el tamaño de la segunda gráfica?

Jason Strimpel
fuente
2
Gridspec funciona con una figura normal.
tillsten

Respuestas:

372

Otra forma es usar la subplotsfunción y pasar la relación de ancho con gridspec_kw:

import numpy as np
import matplotlib.pyplot as plt 

# generate some data
x = np.arange(0, 10, 0.2)
y = np.sin(x)

# plot it
f, (a0, a1) = plt.subplots(1, 2, gridspec_kw={'width_ratios': [3, 1]})
a0.plot(x, y)
a1.plot(y, x)

f.tight_layout()
f.savefig('grid_figure.pdf')
Hagne
fuente
1
Gracias por esto; La plt.subplotsforma de hacer las cosas es mucho más limpia.
Luke Davis
2
Me gustan las subtramas mejor que gridspec ya que ya no tienes que lidiar con la configuración de la lista para el eje (con gridspec aún necesitas hacer el eje y las gráficas una por una). Entonces, las subtramas son más limpias y rápidas de usar
Eelco van Vliet
3
¿Qué sucede si quiero que las dos parcelas en una fila también difieran en altura? El cambio height_ratioparece afectar a toda la fila en relación con otras filas.
Mitchell van Zuylen
Eso no es posible a través de la función de subtramas. Sin embargo, puede agregar algo como esto al código anterior: desde mpl_toolkits.axes_grid1 import make_axes_locatable divider = make_axes_locatable (a0) a_empty = divider.append_axes ("bottom", size = "50%") a_empty.axis ('off')
Hagne
2
Estoy recibiendo este error ValueError: Expected the given number of height ratios to match the number of rows of the grid. Lo resolví diciendo {'width_ratios':[1]}1 fila, etc.
Markus Weber
223

Puedes usar gridspecy figure:

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

# generate some data
x = np.arange(0, 10, 0.2)
y = np.sin(x)

# plot it
fig = plt.figure(figsize=(8, 6)) 
gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1]) 
ax0 = plt.subplot(gs[0])
ax0.plot(x, y)
ax1 = plt.subplot(gs[1])
ax1.plot(y, x)

plt.tight_layout()
plt.savefig('grid_figure.pdf')

trama resultante

bmu
fuente
31

Probablemente la forma más simple es usar subplot2grid, descrito en Personalizar la ubicación de la subtrama usando GridSpec .

ax = plt.subplot2grid((2, 2), (0, 0))

es igual a

import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(2, 2)
ax = plt.subplot(gs[0, 0])

entonces el ejemplo de bmu se convierte en:

import numpy as np
import matplotlib.pyplot as plt

# generate some data
x = np.arange(0, 10, 0.2)
y = np.sin(x)

# plot it
fig = plt.figure(figsize=(8, 6))
ax0 = plt.subplot2grid((1, 3), (0, 0), colspan=2)
ax0.plot(x, y)
ax1 = plt.subplot2grid((1, 3), (0, 2))
ax1.plot(y, x)

plt.tight_layout()
plt.savefig('grid_figure.pdf')
endolito
fuente
29

Solía pyplot's axesobjeto de ajustar manualmente los tamaños sin necesidad de utilizar GridSpec:

import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.2)
y = np.sin(x)

# definitions for the axes
left, width = 0.07, 0.65
bottom, height = 0.1, .8
bottom_h = left_h = left+width+0.02

rect_cones = [left, bottom, width, height]
rect_box = [left_h, bottom, 0.17, height]

fig = plt.figure()

cones = plt.axes(rect_cones)
box = plt.axes(rect_box)

cones.plot(x, y)

box.plot(y, x)

plt.show()
Jason Strimpel
fuente
2
¡Útil para aquellos de nosotros que todavía tenemos matplotlib 0.99 sin gridspec!
Lunes
3
Útil para aquellos donde gridspec es inadecuado
dreab
La mejor respuesta de todas. Exactamente lo que se necesita si desea hacer subtramas de diferentes dimensiones (2D y 3D) y desea que tengan diferentes tamaños. También es bastante fácil de entender. ¡Gracias!
MO