J'ai un tracé avec deux axes y sur un axe x partagé, et je veux les aligner à y = 0 afin de pouvoir dessiner une ligne horizontale pour mettre en évidence la graduation zéro. actuellement les deux axes ne sont pas alignés et je dois tracer deux lignes ce qui est terrible. Comment puis-je y parvenir?
3 Réponses :
En supposant que vous ayez créé les tracés avec un axe partagé, il vous suffit de modifier la plage de y pour qu'elle soit centrée à zéro ou d'avoir un multiplicateur de décalage similaire dans les deux tracés (c'est-à-dire définir ax.set_ylim (-6, 6)
pour les deux tracés). Le code suivant est un exemple.
from matplotlib import pyplot as plt import numpy as np #Create some Fake Data x =np.arange(-10,10) y = x+np.random.rand(20) y2 = 0.5*x-3.*np.random.rand(20) #Figure fig = plt.figure(figsize=(12,6)) #First subplot with zero line not even ax1 = plt.subplot(121) ax2 = ax1.twinx() ax1.plot(x,y,c='r') ax2.plot(x,y2,c='b') ax1.axhline(0) #Second Subplot with zero line the same on both axes ax3 = plt.subplot(122) ax4 = ax3.twinx() ax3.plot(x,y,c='r') ax4.plot(x,y2,c='b') ax3.axhline(0) #If you set your limits on both sides to have the same interval you will get the same zero line ax3.set_ylim(-10,10) ax4.set_ylim(-6,6) plt.show()
Nous devons donc définir manuellement les plages d'axes pour nous assurer qu'elles sont proportionnelles. Pas de possibilité de garder les échelles automatiques mais avec les zéros liés?
Il existe certainement des moyens d'automatiser cela, mais lorsque vous créez l'axe de sous-tracé dans matplotlib, les limites sont définies en fonction de la plage de valeurs. Ainsi, l'automatisation se ferait sur les données et trouverait les meilleurs bords pour garder les lignes zéro identiques.
J'ai trouvé cette excellente bibliothèque qui aligne les axes et maintient la mise à l'échelle automatique.
pip install mpl-axes-aligner
import numpy as np import matplotlib.pyplot as plt import mpl_axes_aligner x = np.arange(0.0, 30, 0.1) y1 = 0.1 * x * np.sin(x) y2 = 0.001*x**3 - 0.03*x**2 + 0.12*x fig = plt.figure() ax1 = fig.add_subplot(111) ax2 = ax1.twinx() ax1.plot(x, y1, color='blue', label='Plot 1') ax2.plot(x, y2, color='red', label='Plot 2') # Align y = 0 of ax1 and ax2 with the center of figure. mpl_axes_aligner.align.yaxes(ax1, 0, ax2, 0, 0.5) plt.show()
Ce package a été développé par ryotuk et l'exemple d'utilisation ci-dessus provient de la documentation de son paquet.
J'ai eu le même problème, et ce que j'ai fait a été de changer l'étendue de l'axe y, en fonction du rapport des limites min / max. Si vous définissez le rapport des axes y comme étant le même, le point zéro devrait être le même.
fig, ax1 = plt.subplots() ax1.plot(...) ax2 = ax1.twinx() ax2.plot(...) ax1_ylims = ax1.axes.get_ylim() ax1_yratio = ax1_ylims[0] / ax1_ylims[1] ax2_ylims = ax2.axes.get_ylim() ax2_yratio = ax2_ylims[0] / ax2_ylims[1] if ax1_yratio < ax2_yratio: ax2.set_ylim(bottom = ax2_ylims[1]*ax1_yratio) else: ax1.set_ylim(bottom = ax1_ylims[1]*ax2_yratio) plt.tight_layout() plt.show()
Ceci est ma première réponse, donc j'espère que c'est suffisant et correct.