Matplotlib 子图太窄且布局紧凑
Matplotlib Subplots Are Too Narrow With Tight Layout
我目前正在尝试使用 GridSpec 在 Matplotlib(Python 3.6,Matplotlib 2.0.0)中绘制许多子图。这是最小的工作示例:
import matplotlib.pyplot as plt
from matplotlib.gridspec import *
# Color vector for scatter plot points
preds = np.random.randint(2, size=100000)
# Setup the scatter plots
fig = plt.figure(figsize=(8,8))
grid = GridSpec(9, 9)
# Create the scatter plots
for ii in np.arange(0, 9):
for jj in np.arange(0, 9):
if (ii > jj):
ax = fig.add_subplot(grid[ii, jj])
x = np.random.rand(100000)*2000
y = np.random.rand(100000)*2000
ax.scatter(x, y, c=preds)
这是没有任何修改的结果:
当然子图之间的间距不尽如人意,所以我按照我平时的做法使用了tight_layout()
。但是从下图可以看出,tight_layout()
压缩了地块的宽度,让人无法接受:
而不是使用 tight_layout()
,我认为我应该使用 subplots_adjust()
手动调整子图。下面是带subplots_adjust(hspace=1.0, wspace=1.0)
.
的图
结果几乎是正确的,再稍微调整一下子图之间的 space 就完美了。然而,子图似乎太小而无法充分传达信息。
有没有更好的方法在子图之间获得适当的间距,同时仍然保持纵横比和足够大的子图大小?我能想到的唯一可能的解决方案是使用 subplots_adjust()
和更大的 figsize
,但这会导致图形边缘和子图之间的 space 非常大。
感谢任何解决方案。
由于您所有的轴都具有相同的 x
和 y
范围,因此我会选择仅在外部 Axes
上显示刻度标签。对于大小相同的子图网格,可以使用 plt.subplots()
的 sharex
和 sharey
关键字轻松实现自动化。当然,如果你设置了一个 9x9 子图的网格,这会给你带来比你想要的更多的图,但你可以使多余的图不可见(例如使用 Axes.set_visible
或完全删除它们。在下面的例子中我选择后者。
from matplotlib import pyplot as plt
import numpy as np
fig, axes = plt.subplots(
nrows=9, ncols=9, sharex=True, sharey=True, figsize = (8,8)
)
# Color vector for scatter plot points
preds = np.random.randint(2, size=1000)
# Create the scatter plots
for ii in np.arange(0, 9):
for jj in np.arange(0, 9):
if (ii > jj):
ax = axes[ii,jj]
x = np.random.rand(1000)*100
y = np.random.rand(1000)*2000
ax.scatter(x, y, c=preds)
else:
axes[ii,jj].remove() ##remove Axes from fig
axes[ii,jj] = None ##make sure that there are no 'dangling' references.
plt.show()
结果图如下所示:
这当然可以用 subplots_adjust()
之类的东西进一步调整。希望这有帮助。
我目前正在尝试使用 GridSpec 在 Matplotlib(Python 3.6,Matplotlib 2.0.0)中绘制许多子图。这是最小的工作示例:
import matplotlib.pyplot as plt
from matplotlib.gridspec import *
# Color vector for scatter plot points
preds = np.random.randint(2, size=100000)
# Setup the scatter plots
fig = plt.figure(figsize=(8,8))
grid = GridSpec(9, 9)
# Create the scatter plots
for ii in np.arange(0, 9):
for jj in np.arange(0, 9):
if (ii > jj):
ax = fig.add_subplot(grid[ii, jj])
x = np.random.rand(100000)*2000
y = np.random.rand(100000)*2000
ax.scatter(x, y, c=preds)
这是没有任何修改的结果:
当然子图之间的间距不尽如人意,所以我按照我平时的做法使用了tight_layout()
。但是从下图可以看出,tight_layout()
压缩了地块的宽度,让人无法接受:
而不是使用 tight_layout()
,我认为我应该使用 subplots_adjust()
手动调整子图。下面是带subplots_adjust(hspace=1.0, wspace=1.0)
.
结果几乎是正确的,再稍微调整一下子图之间的 space 就完美了。然而,子图似乎太小而无法充分传达信息。
有没有更好的方法在子图之间获得适当的间距,同时仍然保持纵横比和足够大的子图大小?我能想到的唯一可能的解决方案是使用 subplots_adjust()
和更大的 figsize
,但这会导致图形边缘和子图之间的 space 非常大。
感谢任何解决方案。
由于您所有的轴都具有相同的 x
和 y
范围,因此我会选择仅在外部 Axes
上显示刻度标签。对于大小相同的子图网格,可以使用 plt.subplots()
的 sharex
和 sharey
关键字轻松实现自动化。当然,如果你设置了一个 9x9 子图的网格,这会给你带来比你想要的更多的图,但你可以使多余的图不可见(例如使用 Axes.set_visible
或完全删除它们。在下面的例子中我选择后者。
from matplotlib import pyplot as plt
import numpy as np
fig, axes = plt.subplots(
nrows=9, ncols=9, sharex=True, sharey=True, figsize = (8,8)
)
# Color vector for scatter plot points
preds = np.random.randint(2, size=1000)
# Create the scatter plots
for ii in np.arange(0, 9):
for jj in np.arange(0, 9):
if (ii > jj):
ax = axes[ii,jj]
x = np.random.rand(1000)*100
y = np.random.rand(1000)*2000
ax.scatter(x, y, c=preds)
else:
axes[ii,jj].remove() ##remove Axes from fig
axes[ii,jj] = None ##make sure that there are no 'dangling' references.
plt.show()
结果图如下所示:
这当然可以用 subplots_adjust()
之类的东西进一步调整。希望这有帮助。