遍历二维子图就像遍历一维数据一样。

15

我想使用子图来绘制大量数据,虽然我没有遇到问题,但我想知道是否有方便的方法来实现这个目标。

以下是示例代码。

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()中的表达式非常丑陋。我不认为我会使用这段代码。 我认为简单的方法是计算子图数量,如果计数> 21,则跳出循环。 但我只是想知道是否有更好(或花哨)的方法。

2个回答

20
< p >subplots 返回一个包含多个坐标轴对象的ndarray数组,您可以使用“flatten”或“ravel”函数将其展平:

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

16

与其使用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()

Example 2

你也可能喜欢GridSpec的外观。


啊……这就是为什么我找不到任何似乎能回答我的问题的东西了!原来问题是无效的。非常感谢!你很快就解决了问题。 - Hoseung Choi
如果你要这样做,至少应该使用fig.add_subplot来确保状态机不会反击。 - tacaswell
如果您想要得到漂亮的图表布局,请使用 fig.tight_layout() - Tom Pohl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接