matplotlib 子图最后一个图扰乱了对数比例
matplotlib subplots last plot disturbs log scale
我正在制作一个 matplotlib
尺寸为 2x2 的图形,其中共享 x 轴和 y 轴,然后循环遍历不同的轴以在其中绘制。我正在绘制每个样本的变体数据,样本可能没有变体数据,所以我希望绘图在中间显示“NA”。
import matplotlib.pyplot as plt
n_plots_per_fig = 4
nrows = 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, sharex="all", sharey="all", figsize=(8, 6))
axs = axs.ravel()
for i, ax in enumerate(axs):
x = [1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] # example values, but this list CAN be empty
bins = 3 # example bins
if x:
ax.hist(x, bins=bins) # plot the hist
ax.set_yscale("log")
ax.set_title(str(i), fontsize="medium")
else:
ax.set_title(str(i), fontsize="medium")
ax.text(0.5, 0.5, 'NA', ha='center', va='center', transform=ax.transAxes)
fig.show()
这几乎适用于所有情况;想要的输出示例:
但是,只有当图中的最后一个图没有任何数据时,才会扰乱对数刻度。触发此操作的示例代码:
import matplotlib.pyplot as plt
n_plots_per_fig = 4
nrows = 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, sharex="all", sharey="all", figsize=(8, 6))
axs = axs.ravel()
for i, ax in enumerate(axs):
x = [1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
bins = 3
if i == n_plots_per_fig-1: # this will distort the log scale
ax.set_title(str(i), fontsize="medium")
ax.text(0.5, 0.5, 'NA', ha='center', va='center', transform=ax.transAxes)
elif x:
ax.hist(x, bins=bins) # plot the hist
ax.set_yscale("log")
ax.set_title(str(i), fontsize="medium")
else:
ax.set_title(str(i), fontsize="medium")
ax.text(0.5, 0.5, 'NA', ha='center', va='center', transform=ax.transAxes)
fig.show()
对数刻度现在设置为非常低的值,这不是我想要的。我已经尝试了几种方法来解决这个问题,比如取消共享没有任何数据的图的 y 轴 [ax.get_shared_y_axes().remove(axis) for axis in axs]
或隐藏图 ax.set_visible(False)
,但是 none 这个作品. 做 的一件事是使用 ax.remove()
从绘图中删除轴,但由于这是最底部的样本,这也删除了 x 刻度的值柱子:
除此之外,我仍然希望没有任何数据的样本的名称在轴(和“NA”文本)中可见,并且删除轴不允许这样做。
关于修复的任何想法?
编辑:我简化了示例。
您可以使用 ax.set_xlim()
/ ax.set_ylim()
手动设置限制。
请注意,如果您共享轴,则在哪个子图中调用这些函数并不重要。例如:
axs[-1][-1].set_ylim(1e0, 1e2)
如果你之前不知道极限,你可以从其他图中推断出来:
x = np.random.random(100)
bins = 10
if bins != 0:
...
yy, xx = np.histogram(x, bins=bins)
ylim = yy.min(), yy.max()
xlim = xx.min(), xx.max()
else:
ax.set_xlim(xlim)
ax.set_ylim(ylim)
我正在制作一个 matplotlib
尺寸为 2x2 的图形,其中共享 x 轴和 y 轴,然后循环遍历不同的轴以在其中绘制。我正在绘制每个样本的变体数据,样本可能没有变体数据,所以我希望绘图在中间显示“NA”。
import matplotlib.pyplot as plt
n_plots_per_fig = 4
nrows = 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, sharex="all", sharey="all", figsize=(8, 6))
axs = axs.ravel()
for i, ax in enumerate(axs):
x = [1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] # example values, but this list CAN be empty
bins = 3 # example bins
if x:
ax.hist(x, bins=bins) # plot the hist
ax.set_yscale("log")
ax.set_title(str(i), fontsize="medium")
else:
ax.set_title(str(i), fontsize="medium")
ax.text(0.5, 0.5, 'NA', ha='center', va='center', transform=ax.transAxes)
fig.show()
这几乎适用于所有情况;想要的输出示例:
但是,只有当图中的最后一个图没有任何数据时,才会扰乱对数刻度。触发此操作的示例代码:
import matplotlib.pyplot as plt
n_plots_per_fig = 4
nrows = 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, sharex="all", sharey="all", figsize=(8, 6))
axs = axs.ravel()
for i, ax in enumerate(axs):
x = [1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
bins = 3
if i == n_plots_per_fig-1: # this will distort the log scale
ax.set_title(str(i), fontsize="medium")
ax.text(0.5, 0.5, 'NA', ha='center', va='center', transform=ax.transAxes)
elif x:
ax.hist(x, bins=bins) # plot the hist
ax.set_yscale("log")
ax.set_title(str(i), fontsize="medium")
else:
ax.set_title(str(i), fontsize="medium")
ax.text(0.5, 0.5, 'NA', ha='center', va='center', transform=ax.transAxes)
fig.show()
对数刻度现在设置为非常低的值,这不是我想要的。我已经尝试了几种方法来解决这个问题,比如取消共享没有任何数据的图的 y 轴 [ax.get_shared_y_axes().remove(axis) for axis in axs]
或隐藏图 ax.set_visible(False)
,但是 none 这个作品. 做 的一件事是使用 ax.remove()
从绘图中删除轴,但由于这是最底部的样本,这也删除了 x 刻度的值柱子:
除此之外,我仍然希望没有任何数据的样本的名称在轴(和“NA”文本)中可见,并且删除轴不允许这样做。
关于修复的任何想法?
编辑:我简化了示例。
您可以使用 ax.set_xlim()
/ ax.set_ylim()
手动设置限制。
请注意,如果您共享轴,则在哪个子图中调用这些函数并不重要。例如:
axs[-1][-1].set_ylim(1e0, 1e2)
如果你之前不知道极限,你可以从其他图中推断出来:
x = np.random.random(100)
bins = 10
if bins != 0:
...
yy, xx = np.histogram(x, bins=bins)
ylim = yy.min(), yy.max()
xlim = xx.min(), xx.max()
else:
ax.set_xlim(xlim)
ax.set_ylim(ylim)