[英]How to make equal grid spacing with secondary axis in matplotlib?
我正在嘗試創建具有相等網格間距的圖,我使用的第一個代碼是:
import numpy as np
import matplotlib.pyplot as plt
time= np.linspace (0, 25, 5000)
temp_pri = 50 / np.sqrt (2 * np.pi * 3**2) * np.exp (-((time - 13)**2 / (3**2))**2) + 15
temp_sec = 50 * np.sin(2* np.pi * time/100)
figure_x_y = plt.figure(figsize=(10, 10))
figure_x_y.clf()
plot_x_vs_y = plt.subplot(111)
plot_x_vs_y.plot(time, temp_pri, linewidth=1.0)
plot_x_vs_y.set_ylabel(r'\textit{Temperature (K)}', labelpad=6)
plot_x_vs_y.set_xlabel(r'\textit{Time (ms)}', labelpad=6)
# plot_x_vs_y.set_aspect('equal')
ax2 = plot_x_vs_y.twinx()
ax2.plot(time, temp_sec, color='#4DAF4A')
# ax2.set_aspect('equal')
plt.show()
plt.close()
我得到的輸出是:
當我將選項set_aspect('equal')選項設置為on時,代碼:
import numpy as np
import matplotlib.pyplot as plt
time= np.linspace (0, 25, 5000)
temp_pri = 50 / np.sqrt (2 * np.pi * 3**2) * np.exp (-((time - 13)**2 / (3**2))**2) + 15
temp_sec = 50 * np.sin(2* np.pi * time/100)
figure_x_y = plt.figure(figsize=(10, 10))
figure_x_y.clf()
plot_x_vs_y = plt.subplot(111)
plot_x_vs_y.plot(time, temp_pri, linewidth=1.0)
plot_x_vs_y.set_ylabel(r'\textit{Temperature (K)}', labelpad=6)
plot_x_vs_y.set_xlabel(r'\textit{Time (ms)}', labelpad=6)
plot_x_vs_y.set_aspect('equal')
ax2 = plot_x_vs_y.twinx()
ax2.plot(time, temp_sec, color='#4DAF4A')
ax2.set_aspect('equal')
plt.show()
plt.close()
我得到的輸出是:
如何使(主要和次要y軸)網格間距相同?
如果用“相同的間距”表示兩個y .ylim()
數字都對齊,則可以使用.ylim()
在兩個.ylim()
設置最小/最大刻度。
#plot_x_vs_y.set_ylim(10,25) # This one is optional, manually set min/max for primary axis.
lims = plot_x_vs_y.get_ylim() # Get min/max of primary y-axis
ax2.set_ylim(lims) # Set min/max of secondary y-axis
ax2.grid('off') # You can turn the grid of secondary y-axis off
plt.show()
這給出:
更新:
為了提供更多的靈活性,您可以在調用plt.show()
之前調用一個輔助函數:
def align_axis(ax1, ax2, step=1):
""" Sets both axes to have the same number of gridlines
ax1: left axis
ax2: right axis
step: defaults to 1 and is used in generating a range of values to check new boundary
as in np.arange([start,] stop[, step])
"""
ax1.set_aspect('auto')
ax2.set_aspect('auto')
grid_l = len(ax1.get_ygridlines()) # N of gridlines for left axis
grid_r = len(ax2.get_ygridlines()) # N of gridlines for right axis
grid_m = max(grid_l, grid_r) # Target N of gridlines
# Choose the axis with smaller N of gridlines
if grid_l < grid_r:
y_min, y_max = ax1.get_ybound() # Get current boundaries
parts = (y_max - y_min) / (grid_l - 1) # Get current number of partitions
left = True
elif grid_l > grid_r:
y_min, y_max = ax2.get_ybound()
parts = (y_max - y_min) / (grid_r - 1)
left = False
else:
return None
# Calculate the new boundary for axis:
yrange = np.arange(y_max + 1, y_max * 2 + 1, step) # Make a range of potential y boundaries
parts_new = (yrange - y_min) / parts # Calculate how many partitions new boundary has
y_new = yrange[np.isclose(parts_new, grid_m - 1)] # Find the boundary matching target
# Set new boundary
if left:
return ax1.set_ylim(top=round(y_new, 0), emit=True, auto=True)
else:
return ax2.set_ylim(top=round(y_new, 0), emit=True, auto=True)
因此,在您的示例中調用它:
align_axis(plot_x_vs_y, ax2)
plt.show()
生產:
這可能比情節的裁剪版本更公平。
請注意,我尚未對其進行廣泛的測試,並且在某些極端情況下,此函數將無法找到正確的對齊值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.