Python 如何在matplotlib中使次轴的栅格间距相等?

Python 如何在matplotlib中使次轴的栅格间距相等?,python,matplotlib,Python,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) fig

我正在尝试创建具有相等网格间距的绘图。我使用的第一个代码是:

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轴)的栅格间距相同?

如果“相同间距”表示两个y轴上的数字对齐,则可以使用
.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()
之前调用它:

产生:

这可能是一个更公平的表现比一个裁剪版本的情节


请注意,我还没有对其进行广泛测试,在极端情况下,此函数可能无法找到正确的对齐值。

这是一个有趣的问题。请注意,添加一个独立的、可复制的示例代码,人们只需复制并在其机器上运行,这将增加人们愿意花时间进行实验的机会。我添加了完整的可复制代码。我没有得到与您显示的相同的图。在标准matplotlib代码中,后台没有网格。您是否导入了其他软件包或更改了
matplotlib
的rc参数的默认设置?我更改了matplotlib的rc参数的默认设置。但是如果刻度的数量级完全不同,该怎么办?请参阅更新的答案。我添加了一个帮助函数来解决这个问题。请注意,如果您需要演示左右y轴之间的任意非线性依赖关系,并且希望在两个轴上都保留漂亮的圆数,下面是一个解决方案:
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()