Sous-parcelles de différentes tailles Matplotlib

238

J'ai besoin d'ajouter deux sous-intrigues à une figure. Une sous-intrigue doit être environ trois fois plus large que la seconde (même hauteur). J'ai accompli cela en utilisant GridSpecet l' colspanargument mais je voudrais le faire en utilisant figureafin que je puisse enregistrer au format PDF. Je peux ajuster le premier chiffre en utilisant l' figsizeargument dans le constructeur, mais comment puis-je changer la taille du deuxième tracé?

Jason Strimpel
la source
2
Gridspec fonctionne avec une figure normale.
tillsten

Réponses:

372

Une autre façon consiste à utiliser la subplotsfonction et à passer le rapport de largeur avec 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
la source
1
Merci pour cela; la plt.subplotsfaçon de faire est beaucoup plus propre.
Luke Davis
2
J'aime mieux les sous-tracés que gridspec car vous n'avez plus à gérer les paramètres de la liste pour l'axe (avec gridspec, vous devez toujours faire l'axe et les tracés un par un). Les sous-parcelles sont donc plus propres et plus rapides à utiliser
Eelco van Vliet
3
Et si je veux que les deux parcelles d'une même rangée diffèrent également en hauteur? La modification height_ratiosemble avoir un impact sur toute la ligne par rapport aux autres lignes.
Mitchell van Zuylen
Ce n'est pas possible grâce à la fonction de sous-parcelles. Cependant, vous pouvez ajouter quelque chose comme ceci au code ci-dessus: à partir de 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
Je reçois cette erreur ValueError: Expected the given number of height ratios to match the number of rows of the grid. Je l'ai résolu en disant {'width_ratios':[1]}pour 1 rang, etc.
Markus Weber
223

Vous pouvez utiliser gridspecet 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')

tracé résultant

bmu
la source
31

La manière la plus simple est probablement d'utiliser subplot2grid, décrite dans Personnalisation de l'emplacement du sous-tracé à l'aide de GridSpec .

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

est égal à

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

alors l'exemple de bmu devient:

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')
endolith
la source
29

J'ai utilisé pyplotl' axesobjet de pour ajuster manuellement les tailles sans utiliser 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
la source
2
Utile pour ceux d'entre nous encore sur matplotlib 0.99 sans gridspec!
jeudi
3
Utile pour ceux où gridspec est inadéquat
dreab
La meilleure réponse de tous les temps. Exactement ce qui est nécessaire si vous souhaitez créer des sous-tracés de différentes dimmensions (2D et 3D) et que vous souhaitez qu'elles aient des tailles différentes. C'est aussi assez facile à comprendre. Je vous remercie!
MO