具有相同绝对比例但不同限制的 Pyplot 子图
Pyplot subplots with equal absolute scale but different limits
我不确定我的措辞是否正确,但我想做的是创建两个子图的图形,其中两个图有不同的限制,但它们的大小使得物理比例(如, y-distance per cm of figure height) 是相同的。澄清一下,假设子图 1 显示从 -3 到 3 的数据,子图 2 显示从 -1 到 1 的数据。我想让它们彼此下方,这样子图 2 的高度(不包括刻度线,只是内部的所有内容) frame) 恰好是子图 1 的三分之一。
我的尝试如下:
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,2, 101)
y1 = 3*np.cos(x*np.pi)
y2 = np.cos(x*np.pi)
fig = plt.figure(figsize=(4, 6))
gs = gridspec.GridSpec(8, 1)
ax1 = plt.subplot(gs[0:6,0])
ax1.plot(x, y1, c='orange')
ax1.set_ylim(-3, 3)
ax1.set_xticks([], [])
ax2 = plt.subplot(gs[6:,0])
ax2.plot(x, y2, c='green')
ax2.set_ylim(-1,1)
ax2.set_xticks([0, 1, 2])
ax2.set_xticklabels([r'0', r'0.5', r'1'])
ax2.set_xlabel(r'$n_g$ (2e)')
plt.tight_layout()
fig.text(-0.025, 0.5, 'Frequency (GHz)', ha='center', va='center', rotation='vertical', size=18)
生成下图,但如您所见(尽管您必须仔细观察)第二个子图中的 -1 到 1 范围比中的 -1 到 1 范围压缩(占用更少的高度)子图 1。我猜这是因为两个子图之间的 space。
请注意,我正在使用 gridspec,因为我计划添加另一列具有有趣纵横比及其自己的标签和限制的子图。如果有人想知道,我不知道如何以更优雅的方式添加全局 ylabel。
您可以设置 gridspec 的 height_ratios
以匹配限制范围。
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,2, 101)
y1 = 3*np.cos(x*np.pi)
y2 = np.cos(x*np.pi)
ylim1 = -3,3
ylim2 = -1,1
fig = plt.figure(figsize=(4, 6), constrained_layout=True)
gs = gridspec.GridSpec(2, 1, height_ratios=[np.diff(ylim1)[0],
np.diff(ylim2)[0]], figure=fig)
ax1 = plt.subplot(gs[0,0])
ax1.plot(x, y1, c='orange')
ax1.set_ylim(ylim1)
ax1.set_xticks([], [])
ax2 = plt.subplot(gs[1,0])
ax2.plot(x, y2, c='green')
ax2.set_ylim(ylim2)
ax2.set_xticks([0, 1, 2])
ax2.set_xticklabels([r'0', r'0.5', r'1'])
ax2.set_xlabel(r'$n_g$ (2e)')
plt.show()
我不确定我的措辞是否正确,但我想做的是创建两个子图的图形,其中两个图有不同的限制,但它们的大小使得物理比例(如, y-distance per cm of figure height) 是相同的。澄清一下,假设子图 1 显示从 -3 到 3 的数据,子图 2 显示从 -1 到 1 的数据。我想让它们彼此下方,这样子图 2 的高度(不包括刻度线,只是内部的所有内容) frame) 恰好是子图 1 的三分之一。
我的尝试如下:
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,2, 101)
y1 = 3*np.cos(x*np.pi)
y2 = np.cos(x*np.pi)
fig = plt.figure(figsize=(4, 6))
gs = gridspec.GridSpec(8, 1)
ax1 = plt.subplot(gs[0:6,0])
ax1.plot(x, y1, c='orange')
ax1.set_ylim(-3, 3)
ax1.set_xticks([], [])
ax2 = plt.subplot(gs[6:,0])
ax2.plot(x, y2, c='green')
ax2.set_ylim(-1,1)
ax2.set_xticks([0, 1, 2])
ax2.set_xticklabels([r'0', r'0.5', r'1'])
ax2.set_xlabel(r'$n_g$ (2e)')
plt.tight_layout()
fig.text(-0.025, 0.5, 'Frequency (GHz)', ha='center', va='center', rotation='vertical', size=18)
生成下图,但如您所见(尽管您必须仔细观察)第二个子图中的 -1 到 1 范围比中的 -1 到 1 范围压缩(占用更少的高度)子图 1。我猜这是因为两个子图之间的 space。
请注意,我正在使用 gridspec,因为我计划添加另一列具有有趣纵横比及其自己的标签和限制的子图。如果有人想知道,我不知道如何以更优雅的方式添加全局 ylabel。
您可以设置 gridspec 的 height_ratios
以匹配限制范围。
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,2, 101)
y1 = 3*np.cos(x*np.pi)
y2 = np.cos(x*np.pi)
ylim1 = -3,3
ylim2 = -1,1
fig = plt.figure(figsize=(4, 6), constrained_layout=True)
gs = gridspec.GridSpec(2, 1, height_ratios=[np.diff(ylim1)[0],
np.diff(ylim2)[0]], figure=fig)
ax1 = plt.subplot(gs[0,0])
ax1.plot(x, y1, c='orange')
ax1.set_ylim(ylim1)
ax1.set_xticks([], [])
ax2 = plt.subplot(gs[1,0])
ax2.plot(x, y2, c='green')
ax2.set_ylim(ylim2)
ax2.set_xticks([0, 1, 2])
ax2.set_xticklabels([r'0', r'0.5', r'1'])
ax2.set_xlabel(r'$n_g$ (2e)')
plt.show()