matplotlib tight_layout无法使轴高度小到足以容纳所有轴装饰

wko9yo5t  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(162)

这不是我第一次遇到这个问题,我通常的解决方法是显式定义图形大小,并沿着避免使用tight_layout(请参见第二个代码示例)。
然而,我发现这个解决方案并不实用,我只想让图形根据其内容自动调整大小,同时考虑到标签,轴标记,轴标签等。
下面是使用tight_layout得到的结果的示例(只是模仿qqplot)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#mock data
df = pd.DataFrame(np.random.randn(500, 200), columns=['var_0', 'var_1','var_2', 'var_3', 'var_4', 
   'var_5', 'var_6', 'var_7','var_8','var_9','var_10', 'var_11', 'var_12',
   'var_13', 'var_14', 'var_15','var_16','var_17', 'var_18','var_19',
   'var_20', 'var_21', 'var_22', 'var_23','var_24', 'var_25', 'var_26',
   'var_27', 'var_28', 'var_29', 'var_30', 'var_31', 'var_32', 'var_33',
   'var_34', 'var_35', 'var_36', 'var_37', 'var_38', 'var_39', 'var_40',
   'var_41', 'var_42', 'var_43', 'var_44', 'var_45', 'var_46', 'var_47',
   'var_48', 'var_49', 'var_50', 'var_51', 'var_52', 'var_53', 'var_54',
   'var_55', 'var_56', 'var_57', 'var_58', 'var_59', 'var_60', 'var_61',
   'var_62', 'var_63', 'var_64', 'var_65', 'var_66', 'var_67', 'var_68',
   'var_69', 'var_70', 'var_71', 'var_72', 'var_73', 'var_74', 'var_75',
   'var_76', 'var_77', 'var_78', 'var_79', 'var_80', 'var_81', 'var_82',
   'var_83', 'var_84', 'var_85', 'var_86', 'var_87', 'var_88', 'var_89',
   'var_90', 'var_91', 'var_92', 'var_93', 'var_94', 'var_95', 'var_96',
   'var_97', 'var_98', 'var_99',
   'var_100', 'var_101', 'var_102', 'var_103', 'var_104', 'var_105',
   'var_106', 'var_107', 'var_108', 'var_109', 'var_110', 'var_111',
   'var_112', 'var_113', 'var_114', 'var_115', 'var_116', 'var_117',
   'var_118', 'var_119', 'var_120', 'var_121', 'var_122', 'var_123',
   'var_124', 'var_125', 'var_126', 'var_127', 'var_128', 'var_129',
   'var_130', 'var_131', 'var_132', 'var_133', 'var_134', 'var_135',
   'var_136', 'var_137', 'var_138', 'var_139', 'var_140', 'var_141',
   'var_142', 'var_143', 'var_144', 'var_145', 'var_146', 'var_147',
   'var_148', 'var_149', 'var_150', 'var_151', 'var_152', 'var_153',
   'var_154', 'var_155', 'var_156', 'var_157', 'var_158', 'var_159',
   'var_160', 'var_161', 'var_162', 'var_163', 'var_164', 'var_165',
   'var_166', 'var_167', 'var_168', 'var_169', 'var_170', 'var_171',
   'var_172', 'var_173', 'var_174', 'var_175', 'var_176', 'var_177',
   'var_178', 'var_179', 'var_180', 'var_181', 'var_182', 'var_183',
   'var_184', 'var_185', 'var_186', 'var_187', 'var_188', 'var_189',
   'var_190', 'var_191', 'var_192', 'var_193', 'var_194', 'var_195',
   'var_196', 'var_197', 'var_198', 'var_199'])
y=np.random.randint(0,2, (500,1))

#something to plot
dfquantiles1=df[y==1].quantile(np.linspace(0,1,101))
dfquantiles0=df[y==0].quantile(np.linspace(0,1,101))

fig,ax = plt.subplots(figsize=(12,12))
for i, var in enumerate(df.iloc[:,:100]):
    plt.subplot(25, 4, i+1)
    ax=plt.gca()
    ax.set_title(var)
    plt.plot(dfquantiles0.loc[:][var],dfquantiles0.loc[:][var])
    plt.plot(dfquantiles0.loc[:][var],dfquantiles1.loc[:][var])
plt.tight_layout()

下面的代码生成了我想要得到的图形。

fig,ax = plt.subplots(25,4,figsize=(14,98))

for i, var in enumerate(df.iloc[:,:100]):
    plt.subplot(25, 4, i+1)
    ax=plt.gca()
    ax.set_title(var)
    ax.plot(dfquantiles0.loc[:][var],dfquantiles0.loc[:][var])
    ax.plot(dfquantiles0.loc[:][var],dfquantiles1.loc[:][var])

但它有一个主要缺点:
我必须明确定义图形大小(这主要是通过反复试验和重复生成图形,这是非常耗时的)。

2izufjch

2izufjch1#

为什么不直接自动缩放figsize参数呢?

from math import ceil

N=100

fig, axs = plt.subplots( ncols=4, nrows=ceil(N/4), layout='constrained',
                         figsize=(3.5 * 4, 3.5 * ceil(N/4)) )

for (i, var), ax in zip(enumerate(df.iloc[:,:N]), axs.flat):
    ax.set_title(var)
    ax.axis('equal')
    ax.plot(dfquantiles0.loc[:][var], dfquantiles0.loc[:][var])
    ax.plot(dfquantiles0.loc[:][var], dfquantiles1.loc[:][var])

我稍微改变了你的绘图程序,使之更直接一些。如果你不喜欢从math导入,你可以用-(-N//4)交换ceil(N/4)

相关问题