在生成small multiples的子图代码中,numpy.ravel()的作用是什么?
plt.subplots()的axes上需要用.ravel()? 我来给你掰扯清楚这个问题,其实核心就是**plt.subplots()返回的axes结构和你要迭代的数据集不匹配**,.ravel()就是用来解决这个错位问题的。
首先,先看你的代码里plt.subplots(6,3)返回的axes是什么:
当你指定了nrows=6和ncols=3时,Matplotlib会返回一个二维数组(形状为(6,3)),每个元素是一个单独的子图Axes对象。简单说就是它的结构是「6行,每行3个Axes」,大概长这样:
[[ax00, ax01, ax02], [ax10, ax11, ax12], ... [ax50, ax51, ax52]]
那如果不用.ravel()会怎么样?
如果你直接写for ax, data in zip(axes, clean_sets),Python会把axes的每一行(比如[ax00, ax01, ax02]这个列表)和clean_sets里的第一个data配对。这时候ax是一个包含3个Axes的数组,你调用ax.plot(data.ETo, "o")肯定会报错——因为数组根本没有plot方法啊!
那.ravel()的作用是什么?
它就像把这个二维的“网格”彻底摊平成一条直线,把原来的(6,3)二维数组变成一个一维数组(形状为(18,)),结构变成:
[ax00, ax01, ax02, ax10, ax11, ax12, ..., ax50, ax51, ax52]
这样一来,zip(axes.ravel(), clean_sets)就能把每个单独的Axes对象和clean_sets里的每个数据集一一对应起来,循环的时候每次拿到的ax都是单个子图,data是单个数据集,调用ax.plot()就完全没问题了。
补充:有没有替代方法?
其实除了.ravel(),你也可以用.flatten(),两者效果在这个场景下几乎一样——都是把多维数组转成一维。区别在于.ravel()返回的是原数组的视图(如果可能的话),而.flatten()返回的是副本,但在你的小图绘制场景里,用哪个都不会有问题。
内容的提问来源于stack exchange,提问作者Dodge

