循环遍历 2d 子图,就好像它是 1-D
loop over 2d subplot as if it's a 1-D
我正在尝试使用子图绘制许多数据,我没有遇到麻烦,但我想知道是否有一种方便的方法可以做到这一点。
下面是示例代码。
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])
此代码循环遍历二维子图数组并在第 21 个图处停止,留下 4 个面板为空。
我的问题是,是否有任何内置方法来完成这项任务?
例如,将 2D 子图数组和 "flatten" 数组转换为 1D,然后通过 0 到 20 遍历 1D 数组。
第二个range()中的表达式非常难看。我不认为我会使用此代码。
我认为简单的方法是计算地块的数量,如果计数 > 21 则中断。
但我只是想知道是否有更好(或更奇特)的方法。
与其使用 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
的外观。
subplots
returns 轴对象的 ndarray,您可以将其展平或拆开:
fig, axes = plt.subplots(nrows = nrow, ncols=ncol, figsize=(8,6))
for ax in axes.flatten()[:20]:
# do stuff to ax
我正在尝试使用子图绘制许多数据,我没有遇到麻烦,但我想知道是否有一种方便的方法可以做到这一点。
下面是示例代码。
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])
此代码循环遍历二维子图数组并在第 21 个图处停止,留下 4 个面板为空。 我的问题是,是否有任何内置方法来完成这项任务? 例如,将 2D 子图数组和 "flatten" 数组转换为 1D,然后通过 0 到 20 遍历 1D 数组。
第二个range()中的表达式非常难看。我不认为我会使用此代码。 我认为简单的方法是计算地块的数量,如果计数 > 21 则中断。 但我只是想知道是否有更好(或更奇特)的方法。
与其使用 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
的外观。
subplots
returns 轴对象的 ndarray,您可以将其展平或拆开:
fig, axes = plt.subplots(nrows = nrow, ncols=ncol, figsize=(8,6))
for ax in axes.flatten()[:20]:
# do stuff to ax