与 this question 非常相似,但不同之处在于我的图可以根据需要变大。
我需要在 matplotlib 中生成一大堆垂直堆叠的图。结果将使用 figsave 保存并在网页上查看,所以我不在乎最终图像的高度,只要子图之间有间距,它们不会重叠。
无论我允许这个数字有多大,子图似乎总是重叠。
我的代码目前看起来像
import matplotlib.pyplot as plt
import my_other_module
titles, x_lists, y_lists = my_other_module.get_data()
fig = plt.figure(figsize=(10,60))
for i, y_list in enumerate(y_lists):
plt.subplot(len(titles), 1, i)
plt.xlabel("Some X label")
plt.ylabel("Some Y label")
plt.title(titles[i])
plt.plot(x_lists[i],y_list)
fig.savefig('out.png', dpi=100)
pandas.DataFrame.plot
,以及 seaborn 轴级图(带有 ax 参数的图):sns.lineplot(..., ax=ax)
尝试使用 plt.tight_layout
举个简单的例子:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=4, ncols=4)
fig.tight_layout() # Or equivalently, "plt.tight_layout()"
plt.show()
没有紧凑的布局
https://i.stack.imgur.com/roV9q.png
https://i.stack.imgur.com/ouSJi.png
您可以使用 plt.subplots_adjust
更改子图之间的间距 (source)
调用签名:
subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
参数含义(和建议的默认值)是:
left = 0.125 # the left side of the subplots of the figure
right = 0.9 # the right side of the subplots of the figure
bottom = 0.1 # the bottom of the subplots of the figure
top = 0.9 # the top of the subplots of the figure
wspace = 0.2 # the amount of width reserved for blank space between subplots
hspace = 0.2 # the amount of height reserved for white space between subplots
实际的默认值由 rc 文件控制
我发现 subplots_adjust(hspace = 0.001) 最终对我有用。当我使用 space = None 时,每个图之间仍然有空白。然而,将其设置为非常接近于零的值似乎会迫使他们排队。我在这里上传的不是最优雅的一段代码,但你可以看到 hspace 是如何工作的。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tic
fig = plt.figure()
x = np.arange(100)
y = 3.*np.sin(x*2.*np.pi/100.)
for i in range(5):
temp = 510 + i
ax = plt.subplot(temp)
plt.plot(x,y)
plt.subplots_adjust(hspace = .001)
temp = tic.MaxNLocator(3)
ax.yaxis.set_major_locator(temp)
ax.set_xticklabels(())
ax.title.set_visible(False)
plt.show()
https://i.stack.imgur.com/52ZH1.png
与 tight_layout
类似,matplotlib 现在(从 2.2 版开始)提供 constrained_layout
。 tight_layout
可以在代码中随时调用以用于单个优化布局,与此相反,constrained_layout
是一个属性,它可能处于活动状态,并且会在每个绘制步骤之前优化布局。
因此,它需要在子图创建之前或期间激活,例如 figure(constrained_layout=True)
或 subplots(constrained_layout=True)
。
例子:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(4,4, constrained_layout=True)
plt.show()
https://i.stack.imgur.com/HcF1b.png
也可以通过 rcParams
设置 constrained_layout
plt.rcParams['figure.constrained_layout.use'] = True
请参阅 what's new entry 和 Constrained Layout Guide
tight_layout
不可靠
tight_layout()
效果更好
contrained_layout
较慢,因为如本答案所示,它在每个绘图步骤之前优化布局。
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(10,60))
plt.subplots_adjust( ... )
plt.subplots_adjust 方法:
def subplots_adjust(*args, **kwargs):
"""
call signature::
subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=None)
Tune the subplot layout via the
:class:`matplotlib.figure.SubplotParams` mechanism. The parameter
meanings (and suggested defaults) are::
left = 0.125 # the left side of the subplots of the figure
right = 0.9 # the right side of the subplots of the figure
bottom = 0.1 # the bottom of the subplots of the figure
top = 0.9 # the top of the subplots of the figure
wspace = 0.2 # the amount of width reserved for blank space between subplots
hspace = 0.2 # the amount of height reserved for white space between subplots
The actual defaults are controlled by the rc file
"""
fig = gcf()
fig.subplots_adjust(*args, **kwargs)
draw_if_interactive()
或者
fig = plt.figure(figsize=(10,60))
fig.subplots_adjust( ... )
图片的大小很重要。
“我尝试过弄乱 hspace,但增加它似乎只会使所有图形变小而没有解决重叠问题。”
因此,为了创造更多的空白空间并保持子图大小,总图像需要更大。
plt.figure(figsize=(10, 7))
,图片的大小将是 2000 x 1400
pix
你可以试试 subplot_tool()
plt.subplot_tool()
使用 pandas.DataFrame.plot 绘制数据框时解决此问题,它使用 matplotlib 作为默认后端。以下适用于指定的 kind=(例如“bar”、“scatter”、“hist”等)
以下适用于指定的 kind=(例如“bar”、“scatter”、“hist”等)
在 python 3.8.12、pandas 1.3.4、matplotlib 3.4.3 中测试
导入和样本数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# sinusoidal sample data
sample_length = range(1, 15+1)
rads = np.arange(0, 2*np.pi, 0.01)
data = np.array([np.sin(t*rads) for t in sample_length])
df = pd.DataFrame(data.T, index=pd.Series(rads.tolist(), name='radians'), columns=[f'freq: {i}x' for i in sample_length])
# display(df.head(3))
freq: 1x freq: 2x freq: 3x freq: 4x freq: 5x freq: 6x freq: 7x freq: 8x freq: 9x freq: 10x freq: 11x freq: 12x freq: 13x freq: 14x freq: 15x
radians
0.00 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.01 0.010000 0.019999 0.029996 0.039989 0.049979 0.059964 0.069943 0.079915 0.089879 0.099833 0.109778 0.119712 0.129634 0.139543 0.149438
0.02 0.019999 0.039989 0.059964 0.079915 0.099833 0.119712 0.139543 0.159318 0.179030 0.198669 0.218230 0.237703 0.257081 0.276356 0.295520
# default plot with subplots; each column is a subplot
axes = df.plot(subplots=True)
https://i.stack.imgur.com/9K9iM.png
调整间距
调整 pandas.DataFrame.plot 中的默认参数 更改 figsize:每个子图的宽度为 5 和高度为 4 是一个很好的起点 更改布局:(行、列)用于子图的布局。 sharey=True 和 sharex=True 因此不会为每个子图上的冗余标签占用空间。
更改 figsize:每个子图的宽度为 5,高度为 4 是一个不错的起点
更改布局:(行、列)用于子图的布局。
sharey=True 和 sharex=True 因此不会为每个子图上的冗余标签占用空间。
.plot 方法返回一个 matplotlib.axes.Axes 的 numpy 数组,应该将其展平以便于使用。
使用 .get_figure() 从其中一个轴中提取 DataFrame.plot 图形对象。
如果需要,请使用 fig.tight_layout()。
axes = df.plot(subplots=True, layout=(3, 5), figsize=(25, 16), sharex=True, sharey=True)
# flatten the axes array to easily access any subplot
axes = axes.flat
# extract the figure object
fig = axes[0].get_figure()
# use tight_layout
fig.tight_layout()
https://i.stack.imgur.com/ncA2i.png
fig.tight_layout()
之后。可以把这个功能想象成“我的图形布局太紧了,请重新调整”