【问题标题】:Matplotlib automatically scale vertical height of subplots for shared x-axis figureMatplotlib 自动缩放共享 x 轴图形的子图的垂直高度
【发布时间】:2017-12-07 19:07:05
【问题描述】:

我想根据数据跨度自动缩放共享 x 轴图形的子图的垂直高度!我想比较显示数据的相对强度。如果我对 subbplots 使用 sharey=True kwarg,则数据以相对强度可识别的方式显示:

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

    SIZE = (12, 8) #desired overall figure size


    # Simple data to display in various forms
    x = np.linspace(0, 2 * np.pi, 400)

    y = np.sin(x ** 2)
    y2 = 2*(np.sin(x ** 2))
    y3 = 3*(np.sin(x ** 2))


    fig, ax = plt.subplots(3,ncols=1, sharex=True, sharey=True)
    fig.set_size_inches(SIZE[1], SIZE[0])
    fig.subplots_adjust(hspace=0.001)


    ax[0].plot(x, y)
    ax[1].plot(x, y2)
    ax[2].plot(x, y3)
    plt.show()

所有子图现在都具有相同的高度,并且 y 轴上的数据跨度是可识别的,因为数据以正确的相对比例显示。 我想要实现的是每个绘图的比例都在数据结束的地方结束。基本上消除了未使用的空白。子图的大小将代表数据的相对高度比。它们在 Y 轴上仍应具有相同的缩放比例,以便查看者估计相对数据高度(例如,它是一个计数)。

我找到了类似问题的以下链接,但没有一个真正帮助我解决我的问题:

Link1Link2

【问题讨论】:

    标签: python matplotlib height subplot


    【解决方案1】:

    这是一个为您确定比率并相应地创建子图的示例:

    import matplotlib.pyplot as plt
    from matplotlib import gridspec
    import numpy as np
    
    SIZE = (12, 8) #desired overall figure size
    
    # Simple data to display in various forms
    x = np.linspace(0, 2 * np.pi, 400)
    
    # the maximum multiplier for the function
    N = 3
    
    # the y-ranges:
    ys = [i * np.sin(x**2) for i in range(1,N+1)]
    
    # the maximum extent of the plot in y-direction (cast as int)
    hs = [int(np.ceil(np.max(np.abs(y)))) for y in ys]
    
    # determining the size of the GridSpec:
    gs_size = np.sum(hs)
    gs = gridspec.GridSpec(gs_size,1)
    
    # the figure
    fig = plt.figure(figsize = SIZE)
    
    # creating the subplots
    base = 0
    ax = []
    for y,h in zip(ys,hs):
        ax.append(fig.add_subplot(gs[base:h+base,:]))
        base += h
        ax[-1].plot(x,y)
    
    ##fig, ax = plt.subplots(3,ncols=1, sharex=True, sharey=True)
    ##fig.set_size_inches(SIZE[1], SIZE[0])
    fig.subplots_adjust(hspace=0.001)
    
    
    ##ax[0].plot(x, ys[0])
    ##ax[1].plot(x, ys[1])
    ##ax[2].plot(x, ys[2])
    plt.show()
    

    代码确定每组数据的最大 y 扩展,将其转换为整数,然后使用这些扩展的总和作为GridSpec 的比例将图形划分为子图。

    生成的图形如下所示:

    在 Python 3.5 上测试

    编辑

    如果您的数据的最大和最小范围不可比较,最好将hs 的计算方式更改为

    hs = [int(np.ceil(np.max(y))) - int(np.floor(np.min(y))) for y in ys]
    

    【讨论】:

    • 这回答了我的问题!谢谢!我不确定我是否完全理解它,但我会尝试:-)
    • @NorrinRadd 如果您有任何特殊问题,请随时提问。
    • 基本上我正在努力改变这个公式` hs = [int(np.ceil(np.max(y))) - int(np.floor(np.min(y))) for y in ys]` 以某种方式从我的实验数据中读取值。我在一个循环中填充我的轴(ax)对象,而不是我有nrows 的轴对象。我不确定如何遍历存储在此对象中的 y 值。我试过:hs = [int(np.ceil(np.max(y))) - int(np.floor(np.min(y))) for y in axis.get_ydata()] 但这会导致AttributeError: 'numpy.ndarray' object has no attribute 'get_ydata'
    • @NorrinRadd 来自您的评论,很难知道您要做什么,但您绝对应该在创建子图之前 计算轴高度。您如何加载实验数据?
    • 我用一个特定的类读取我的数据,该类在其他东西旁边创建一个熊猫数据框 ´data_frame = pd.DataFrame(data=data, index=index, columns=columns)` 读取数据函数返回像这样的对象:return Data(filename, data_frame, title, path, source)。绘图功能创建像这样的绘图:ax.plot(self.data.index, self.data.columns,kwargs),我根据我想要绘制的数据量,在循环中从我的主绘图脚本中调用它。包含实验数据的column 通常称为EXP
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2016-10-10
    • 2019-05-31
    • 2019-03-22
    • 1970-01-01
    • 2014-12-25
    相关资源
    最近更新 更多