gridspec 和共享 yaxis 的问题:如何正确格式化?

Posted

技术标签:

【中文标题】gridspec 和共享 yaxis 的问题:如何正确格式化?【英文标题】:Issue with gridspec and shared yaxis: how to format properly? 【发布时间】:2022-01-13 04:39:32 【问题描述】:

我正在尝试修复此图的格式:

我正在使用“Df”数据生成,但我遇到了这个麻烦的问题,其中两个图都太接近了。我用来绘制的脚本是:

#[Df,mdD,teoD,e1f,teoe1,e2f,teoe2] = [[row[i] for row in np.load('master_results.npy',allow_pickle=True)[1][2:]] for i in [0,1,2,3,4,5,6]] #reading Datafile

import matplotlib.gridspec as gridspec

def test_histograms(values):

    fig = plt.figure(figsize=(25,15))

    gs = gridspec.GridSpec(3, 3)
    ax_main = plt.subplot(gs[1:3, :2])
    ax_yDist = plt.subplot(gs[1:3, 2],sharey=ax_main)

    ax_main.plot(np.arange(len(values)),values, alpha=0.05)
    ax_main.scatter(np.arange(len(values)),values, s=20, marker='o',alpha=0.4)
    values.sort()
    ax_main.plot(values, linewidth=3)

    ax_main.set(xlabel="Test number", ylabel=r"$\Delta(t_f)$")
    ax_main.grid(True, color='blue', linewidth=3, linestyle='--', alpha=0.1)
    ax_main.legend(['_nolegend_', r'$\Delta(t=t_f)$', '$\Delta(t_f)^\;\mathrm(sorted)$'])

    ax_yDist.hist(values,bins=100,orientation='horizontal',align='mid', alpha=0.5)
    ax_yDist.hlines(0.0359,0,26,linestyle='--',color='blue')
    ax_yDist.grid(True, color='blue', linewidth=3, linestyle='--', alpha=0.1)
    ax_yDist.set(xlabel='count')
    ax_yCumDist = ax_yDist.twiny()
    ax_yCumDist.hist(values,bins=100,cumulative=True,histtype='step',density=True,color='green',align='mid',orientation='horizontal',linewidth=3)
    ax_yCumDist.tick_params('x', colors='green')
    ax_yCumDist.set_xlabel('cumulative',color='green')

    plt.show()

test_histograms(Df)
Df=np.random.uniform(0.0359, 0.0018, 400)
test_histograms(Df)
Df=np.random.rayleigh(0.0359, 400)
test_histograms(Df)
Df=np.random.normal(0.0359, 0.0018, 400)
test_histograms(Df)

您可以使用不同的分布来实现可重复性。具体来说,对于 3 个十进制值,第二个(右侧)y 轴离左侧太近了。我希望看到类似的东西

第二个情节,但对于任何可能的范围。我该如何解决这个问题?也许在左右图之间添加一个薄的“空间”?

【问题讨论】:

【参考方案1】:

使用tight_layout() 函数调整子图之间和周围的填充:

plt.tight_layout()

代码:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import gridspec as gridspec

def test_histograms(values):

    fig = plt.figure(figsize=(25,15))

    gs = gridspec.GridSpec(3, 3)
    ax_main = plt.subplot(gs[1:3, :2])
    ax_yDist = plt.subplot(gs[1:3, 2],sharey=ax_main)

    _ = ax_main.plot(np.arange(len(values)),values, alpha=0.05)
    ax_main.scatter(np.arange(len(values)),values, s=20, marker='o',alpha=0.4)
    values.sort()
    _ = ax_main.plot(values, linewidth=3)

    ax_main.set(xlabel="Test number", ylabel=r"$\Delta(t_f)$")
    ax_main.grid(True, color='blue', linewidth=3, linestyle='--', alpha=0.1)
    ax_main.legend(['_nolegend_', r'$\Delta(t=t_f)$', '$\Delta(t_f)^\;\mathrm(sorted)$'])

    ax_yDist.hist(values,bins=100,orientation='horizontal',align='mid', alpha=0.5)
    ax_yDist.hlines(0.0359,0,26,linestyle='--',color='blue')
    ax_yDist.grid(True, color='blue', linewidth=3, linestyle='--', alpha=0.1)
    ax_yDist.set(xlabel='count')
    ax_yCumDist = ax_yDist.twiny()
    ax_yCumDist.hist(values,bins=100,cumulative=True,histtype='step',density=True,color='green',align='mid',orientation='horizontal',linewidth=3)
    ax_yCumDist.tick_params('x', colors='green')
    ax_yCumDist.set_xlabel('cumulative',color='green')

    plt.tight_layout()
    plt.show()

df = np.random.uniform(0.0359, 0.0018, 400)
test_histograms(df)
df = np.random.rayleigh(0.0359, 400)
test_histograms(df)
df = np.random.normal(0.0359, 0.0018, 400)
test_histograms(df)

添加tight_layout前的输出:

添加tight_layout后的输出:

注意: 您可以使用tight_layout 的w_pad 参数来设置子图之间的填充,例如使用plt.tight_layout(w_pad=10) 将导致以下结果:

【讨论】:

我正在寻找的解决方案。很有用,谢谢!两个问题:为什么标记的大小会因您显示的图而改变,但在代码中却没有?你只是改变了s=20还是别的什么?为什么将 ax_main 定义为 _ ?我应该吗? 我将ax_main 定义为_,因为在jupyter 中它会向控制台打印一些行,但它不是必需的,这只是为了我的方便。关于标记大小,我没有更改大小,我将其保留为s=20,可能由于我的分辨率或我运行代码的位置而看起来不同..

以上是关于gridspec 和共享 yaxis 的问题:如何正确格式化?的主要内容,如果未能解决你的问题,请参考以下文章

Python seaborn可视化:组合多个seaborn可视化结果并使得组合结果图像共享Y轴使用matplotlib的subplots子图函数的gridspec_kw参数指定子图的相对大小或者比率

如何将 seaborn 的 catplot 绘制到 gridspec

Matplotlib 使用GridSpec和其他功能自定义图形布局

创建一个图形,其中包含按 gridspec 布局排列的绘图、滑块和其他小部件

如何使子图的大小相等?

多个子图的GridSpec“正在清除包含传递轴的图形”