Comment sharex utiliser subplot2grid
Je suis un utilisateur de Matlab récemment converti en Python. La plupart des compétences en Python que je gère sur mon propre, mais avec le complot j'ai frappé le mur et besoin d'aide.
c'est Ce que je suis en train de faire...
j'ai besoin de faire une figure qui se compose de 3 sous-intrigues avec les propriétés suivantes:
- la disposition des sous-lots est 311, 312, 313
- la hauteur de 312 et 313 est environ la moitié du 311
- toutes les sous-parcelles partagent le même X axe
- l'espace entre les sous-lots est 0 (ils se touchent à l'axe des X)
par la façon dont je sais faire tout cela, mais pas en un seul chiffre. C'est le problème que je me pose maintenant.
Par exemple, c'est mon idéal intrigue secondaire mise en page:
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)
s2 = np.exp(-t)
s3 = s1*s2
fig = plt.figure()
ax1 = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2)
ax2 = plt.subplot2grid((4,3), (2,0), colspan=3)
ax3 = plt.subplot2grid((4,3), (3,0), colspan=3)
ax1.plot(t,s1)
ax2.plot(t[:150],s2[:150])
ax3.plot(t[30:],s3[30:])
plt.tight_layout()
plt.show()
remarquez comment l'axe x des différents sous-lots est mal aligné. Je ne sais pas comment faire pour aligner l'axe des x dans cette figure, mais si je fais quelque chose comme ceci:
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)
s2 = np.exp(-t)
s3 = s1*s2
fig2, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, sharex=True)
ax1.plot(t,s1)
ax2.plot(t[:150],s2[:150])
ax3.plot(t[30:],s3[30:])
plt.tight_layout()
plt.show()
maintenant le x l'axe est aligné entre les sous-intrigues, mais tous les sous-intrigues sont de la même taille (ce qui n'est pas ce que je veux)
de plus, j'aimerais que les sous-lots touchent à l'axe x comme ceci:
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)
s2 = np.exp(-t)
s3 = s1*s2
fig1 = plt.figure()
plt.subplots_adjust(hspace=0)
ax1 = plt.subplot(311)
ax2 = plt.subplot(312, sharex=ax1)
ax3 = plt.subplot(313, sharex=ax1)
ax1.plot(t,s1)
ax2.plot(t[:150],s2[:150])
ax3.plot(t[30:],s3[30:])
xticklabels = ax1.get_xticklabels()+ax2.get_xticklabels()
plt.setp(xticklabels, visible=False)
plt.show()
alors pour reformuler ma question:
je voudrais utiliser
plt.subplot2grid(..., colspan=3, rowspan=2)
plt.subplots(..., sharex=True)
plt.subplots_adjust(hspace=0)
et
plt.tight_layout()
dans la même figure. Comment faire?
2 réponses
spécifiez juste sharex=ax1
lors de la création de vos deuxième et troisième sous-lots.
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)
s2 = np.exp(-t)
s3 = s1*s2
fig = plt.figure()
ax1 = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2)
ax2 = plt.subplot2grid((4,3), (2,0), colspan=3, sharex=ax1)
ax3 = plt.subplot2grid((4,3), (3,0), colspan=3, sharex=ax1)
ax1.plot(t,s1)
ax2.plot(t[:150],s2[:150])
ax3.plot(t[30:],s3[30:])
fig.subplots_adjust(hspace=0)
for ax in [ax1, ax2]:
plt.setp(ax.get_xticklabels(), visible=False)
# The y-ticks will overlap with "hspace=0", so we'll hide the bottom tick
ax.set_yticks(ax.get_yticks()[1:])
plt.show()
Si vous avez encore ce qu'il faut utiliser fig.tight_layout()
, vous aurez besoin de l'appeler avantfig.subplots_adjust(hspace=0)
. La raison pour cela est que tight_layout
fonctionne en calculant automatiquement les paramètres pour subplots_adjust
puis en l'appelant, de sorte que si subplots_adjust
est manuellement appelé en premier, tout dans le premier appel à lui sera dépassé par tight_layout
.
E. G.
fig.tight_layout()
fig.subplots_adjust(hspace=0)
une solution possible est de créer manuellement l'axe en utilisant le add_axis
méthode comme le montre ici:
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)
s2 = np.exp(-t)
s3 = s1*s2
left, width = 0.1, 0.8
rect1 = [left, 0.5, width, 0.4]
rect2 = [left, 0.3, width, 0.15]
rect3 = [left, 0.1, width, 0.15]
fig = plt.figure()
ax1 = fig.add_axes(rect1) #left, bottom, width, height
ax2 = fig.add_axes(rect2, sharex=ax1)
ax3 = fig.add_axes(rect3, sharex=ax1)
ax1.plot(t,s1)
ax2.plot(t[:150],s2[:150])
ax3.plot(t[30:],s3[30:])
# hide labels
for label1,label2 in zip(ax1.get_xticklabels(),ax2.get_xticklabels()):
label1.set_visible(False)
label2.set_visible(False)
plt.show()
mais vous ne pouvez pas utiliser tight_layout
comme vous le définir explicitement la taille de chaque axe.