当具有不同比例(双轴)的地块时,如何将两个地块并排放置?

How do I put two plots next to each other when having plots with different scales (twinaxes)?

我有两个图,但绘制在同一个 x 轴上。我想将两个图并排绘制(并排),而不是垂直绘制。 我该怎么做?

从 matplotlib 文档中借用的示例数据。我试过了,我把第一个图放到了 plt.subplots 中,但是第二个图仍然绘制在下面而不是第一个图旁边:

import numpy as np
import matplotlib.pyplot as plt

# Create some mock data
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)


## initiating the plots next to each other 

fig,(ax1,ax2) = plt.subplots(1,2)

color = 'tab:red'
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax2.plot(t, data2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
plt.xlim(0,4)

fig.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()


fig, ax1 = plt.subplots()

color = 'tab:red'
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax2.plot(t, data2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
plt.xlim(4,6)

fig.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()

这种情况下,最简单的方法就是使用Gridspec进行布局。图中的代码直接改编自您的代码。另一方面,我只创建了结构。这个结构以后可以扩展。

import matplotlib.pyplot as plt
from matplotlib import gridspec
import numpy as np

# Create some mock data
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)

fig = plt.figure(figsize=(10, 8))
gs = gridspec.GridSpec(nrows=1, ncols=2, width_ratios=[1,1], wspace=0.5)
ax1 = fig.add_subplot(gs[0])
color = 'tab:red'
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax2.plot(t, data2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
plt.xlim(0,4)

ax3 = fig.add_subplot(gs[1])
color = 'tab:red'
ax3.set_xlabel('time (s)')
ax3.set_ylabel('exp', color=color)
ax3.plot(t, data1, color=color)
ax3.tick_params(axis='y', labelcolor=color)

ax4 = ax3.twinx()  # instantiate a second axes that shares the same x-axis

color = 'tab:blue'
ax4.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax4.plot(t, data2, color=color)
ax4.tick_params(axis='y', labelcolor=color)
plt.xlim(4,6)

plt.show()

这里实际上需要 4 个地块。因此,我将 ax1 和 ax2 用于左侧的绘图,将 ax3 和 ax4 用于右侧的绘图。我不确定这是最好的方法,但我认为它可以解决您的问题。

import numpy as np
import matplotlib.pyplot as plt

# Create some mock data
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)


## initiating the plots next to each other 

fig,(ax1,ax3) = plt.subplots(1,2)

color = 'tab:red'
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)

ax2=ax1.twinx()

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax2.plot(t, data2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_xlim([0,4])



color = 'tab:red'
ax3.set_xlabel('time (s)')
ax3.set_ylabel('exp', color=color)
ax3.plot(t, data1, color=color)
ax3.tick_params(axis='y', labelcolor=color)

ax4=ax3.twinx()

color = 'tab:blue'
ax4.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax4.plot(t, data2, color=color)
ax4.tick_params(axis='y', labelcolor=color)
ax4.set_xlim(4,6)



fig.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()

Plots

我想指出这一点,

  • 您通常不会在完成 plt.show() 后进行绘图。

您可以先创建所有 axes,然后再使用它们。参考下面的例子。

import numpy as np
import matplotlib.pyplot as plt

# Create some mock data
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)

f = plt.figure(figsize=(10,3))

# create all axes we need
ax1 = plt.subplot(121)
ax2 = ax1.twinx()
ax3 = plt.subplot(122)
ax4 = ax3.twinx()

# share the secondary axes
ax1.get_shared_y_axes().join(ax1, ax3)

color = 'tab:red'
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax1.grid()

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax2.plot(t, data2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
plt.xlim(0,4)

color = 'tab:red'
ax3.set_xlabel('time (s)')
ax3.set_ylabel('exp', color=color)
ax3.plot(t, data1, color=color)
ax3.tick_params(axis='y', labelcolor=color)
ax3.grid()

color = 'tab:blue'
ax4.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax4.plot(t, data2, color=color)
ax4.tick_params(axis='y', labelcolor=color)
plt.xlim(4,6)

plt.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()

输出图像: