在 For 循环 Matplotlib 中创建子图

Posted

技术标签:

【中文标题】在 For 循环 Matplotlib 中创建子图【英文标题】:Create Subplots in For Loop Matplotlib 【发布时间】:2020-07-23 15:42:33 【问题描述】:

我正在尝试使用 matplotlib 制作 3,2 子图,但在阅读文档后我不明白如何执行此操作,因为它适用于我的代码,如下所示:

import pandas as pd
from sys import exit
import numpy as np
import matplotlib.pyplot as plt
import datetime
import xarray as xr
import cartopy.crs as ccrs
import calendar

list = [0,1,2,3,4,5]
now = datetime.datetime.now()
currm = now.month
import calendar
fig, axes = plt.subplots(nrows=3,ncols=2)
fig.subplots_adjust(hspace=0.5)
fig.suptitle('Teleconnection Pos+ Phases  2020'.format(calendar.month_name[currm-1]))
#for x in list: 
#for ax, x in zip(axs.ravel(), list):
for x, ax in enumerate(axes.flatten()):
        dam = DS.where(DS['time.year']==rmax.iloc[x,1]).groupby('time.month').mean()#iterate by index 
of column "1" or the years
        dam = dam.sel(month=3)#current month mean 500
        dam = dam.sel(level=500)
        damc = dam.to_array()
        lats = damc['lat'].data
        lons = damc['lon'].data
#plot data
        ax = plt.axes(projection=ccrs.PlateCarree())
        ax.coastlines(lw=1)
        damc = damc.squeeze()
        ax.contour(lons,lats,damc,cmap='jet')
        ax.set_title(tindices[x])
        plt.show()
#plt.clf()

我已经尝试了多个选项,其中一些在 cmets 上面,但我无法让子图显示在我期待的 3,2 子图中。我只得到单个地块。我在下面的 for 循环中包含了第一个图,您可以看到它没有绘制在 3,2 子图区域内:

[![enter image description here][1]][1]

带有“ax.contour”的行可能是问题,但我不确定。非常感谢,下面是我的目标子图区域:

[![enter image description here][1]][1]

【问题讨论】:

请在代码顶部包含所有import 行,最好是reproducible example 的示例数据。另外,您对问题的描述不是很清楚。如果六个图呈现在一列上,问题是什么? 对不起,我的代码很长,所以我的重点是 for 循环,我现在在顶部添加了几行。我已经编辑了这个问题,让我明白我根本没有得到子图——我总共只得到 6 个图,在循环中一次生成一个。希望这更清楚。谢谢 【参考方案1】:

如果没有可重现的样本数据,则无法测试以下内容。但是,您的循环分配了一个新的 ax 并且不使用正在迭代的 ax。此外,plt.show() 被放置在循环中。考虑以下调整

for x, ax in enumerate(axes.flatten()):
    ...
    ax = plt.axes(projection=ccrs.PlateCarree())
    ...
    plt.show()

考虑将 projection 放在 plt.subplots 中,然后在循环内索引 axes

fig, axes = plt.subplots(nrows=3, ncols=2, subplot_kw='projection': ccrs.PlateCarree())
fig.subplots_adjust(hspace=0.5)
fig.suptitle('Teleconnection Pos+ Phases  2020'.format(calendar.month_name[currm-1]))

axes = axes.flatten()

for x, ax in enumerate(axes):
        dam = DS.where(DS['time.year']==rmax.iloc[x,1]).groupby('time.month').mean()

        dam = dam.sel(month=3)#current month mean 500
        dam = dam.sel(level=500)
        damc = dam.to_array()
        lats = damc['lat'].data
        lons = damc['lon'].data

        axes[x].coastlines(lw=1)
        damc = damc.squeeze()
        axes[x].contour(lons, lats, damc, cmap='jet')
        axes[x].set_title(tindices[x])

plt.show() 
plt.clf()

【讨论】:

谢谢你——我马上得到了空白矩形中的 3,2 子图网格,但在第一次循环迭代中立即出现了这个错误:AttributeError: 'numpy.ndarray' object has no attribute 'coastlines' 尝试在循环中用ax替换所有axes[x] 我必须将第一行更改为此进行投影--> fig, axes = plt.subplots(nrows=3,ncols=2,subplot_kw='projection': ccrs.PlateCarree( ))....它正在工作或尝试,但我只是在左上角或位置 1,1 有第一个图,所有其他空间都是完全空的/白色的。完成时没有错误。我在循环中替换了轴[x]。 查看更新。我们需要 flatten axes 之前不在循环期间。 它有效!将 plt.show() 和 plt.clf() 移到循环之外就可以了——谢谢!!

以上是关于在 For 循环 Matplotlib 中创建子图的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 matplotlib 创建子图的大图?

关于 matplotlib

在 for 循环中调整 matplotlib 散点图大小

Matplotlib空白图(应该有子图)

如何从 for 循环中为 matplotlib 图设置动画

matplotlib 基础