【问题标题】:loop over 2d subplot as if it's a 1-D像一维一样循环二维子图
【发布时间】:2015-03-20 04:33:48
【问题描述】:

我正在尝试使用子图绘制许多数据,我没有遇到麻烦,但我想知道是否有一种方便的方法可以做到这一点。

下面是示例代码。

import numpy as np    
import math 
import matplotlib.pyplot as plt

quantities=["sam_mvir","mvir","rvir","rs","vrms","vmax"
,"jx","jy","jz","spin","m200b","m200c","m500c","m2500c"
,"xoff","voff","btoc","ctoa","ax","ay","az"]

# len(quantities) = 21, just to make the second loop expression 
# shorter in this post.

ncol = 5
nrow = math.ceil(21 / ncol)

fig, axes = plt.subplots(nrows = nrow, ncols=ncol, figsize=(8,6))

for i in range(nrow):
    for j in range(((21-i*5)>5)*5 + ((21-i*5)<5)*(21%5)):
        axes[i, j].plot(tree[quantities[i*ncol + j]]) 
        axes[i, j].set_title(quantities[i*ncol + j])

此代码循环遍历子图的 2D 数组并在第 21 个图处停止,留下 4 个面板为空。 我的问题是,有没有内置的方法来完成这项任务? 例如,制作 2D 子图数组并将数组“展平”为 1D,然后在 0 到 20 之间循环遍历 1D 数组。

第二个 range() 中的表达式非常难看。我不认为我会使用这段代码。 我认为最简单的方法是计算地块的数量并在 count > 21 时中断。 但我只是想知道是否有更好(或花哨)的方法。

【问题讨论】:

    标签: python matplotlib flatten subplot


    【解决方案1】:

    与其使用plt.subplots 提前创建子图,不如使用plt.subplot(nrows, ncols, number) 随时创建它们。下面的小例子展示了如何做到这一点。它创建了一个 3x3 的绘图数组,并且只绘制了前 6 个。

    import numpy as np
    import matplotlib.pyplot as plt
    
    nrows, ncols = 3, 3
    
    x = np.linspace(0,10,100)
    
    fig = plt.figure()    
    for i in range(1,7):
        ax = fig.add_subplot(nrows, ncols, i)
        ax.plot(x, x**i)
    
    plt.show()
    

    您当然可以通过 plt.subplot(nrows, ncols, i) 填写最后三个,但不要在其中调用任何绘图(如果这是您想要的)。

    import numpy as np
    import matplotlib.pyplot as plt
    
    nrows, ncols = 3, 3
    
    x = np.linspace(0,10,100)
    
    fig = plt.figure()    
    for i in range(1,10):
        ax = fig.add_subplot(nrows, ncols, i)
        if i < 7:
            ax.plot(x, x**i)
    
    plt.show()
    

    你可能也喜欢GridSpec的样子。

    【讨论】:

    • 啊.....这就是为什么我能找到任何似乎可以回答我的问题的东西......!这个问题只是无效的。非常感谢!很快。
    • 如果你打算这样做,你至少应该使用fig.add_subplot来确保状态机不会反击。
    【解决方案2】:

    subplots 返回轴对象的 ndarray,您可以将其展平或拆散:

    fig, axes = plt.subplots(nrows = nrow, ncols=ncol, figsize=(8,6))
    for ax in axes.flatten()[:20]:
        # do stuff to ax
    

    【讨论】:

      猜你喜欢
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 2021-07-18
      • 1970-01-01
      • 2016-05-01
      • 2016-06-25
      相关资源
      最近更新 更多