【问题标题】:Is it possible to plot contours on top of data in matplotlib (python)?是否可以在 matplotlib(python)中的数据之上绘制轮廓?
【发布时间】:2021-11-03 18:14:49
【问题描述】:

下面是我为一组数据创建的图,顶部绘制了轮廓。这正是我所需要的,我只需要将它绘制为我的 7 次模型运行的一系列子图,其中包含彩色盐度数据和顶部绘制的等高线。

但是,当我尝试绘制子图时,我可以获得盐度数据,但我无法在顶部(或颜色条,但这是另一个问题)上绘制轮廓。理想情况下,这应该看起来像图 1 的 7 个迷你版本。但是,我收到以下错误:

TypeError: inner() got multiple values for argument 'ax'

当我绘制与单个图形相同的东西时,我没有得到它,并且找不到解决方法。

不幸的是,每个数据文件都是 5GB,所以我无法上传它们。例如,我创建了一个虚拟数据集和一个基本绘图脚本来尝试在数据上绘制轮廓。我还创建了一些轮廓,虽然它们与我的不完全一样,因为我的是测深仪,所以需要转换。

抱歉有任何错误 - python 很新! 非常感谢任何建议,以及如何提高我的提问能力!

import xarray as xa
import numpy as np
import matplotlib.pyplot as plt
import cmocean.cm as cm
import cartopy.crs as ccrs

#-----------Example Salinity Data---------------

data1 = 15 + 8 * np.random.randn(4,3)
salinity1 = xa.DataArray(data1)
salinity1 = xa.DataArray(data1, dims=['lat', 'lon'])
lons = np.linspace(-2, 6, 3)
lats = np.linspace(54, 62, 4)
salinity1 = xa.DataArray(data1, coords=[lats, lons], dims=['lat', 'lon'])
salt_ocean1 = salinity1

#-----------Example Contour Data---------------

xp = np.arange(-8, 10, 2)
yp = np.arange(-8, 10, 2)
zp = np.ndarray((9,9))
for x in range(0, len(xp)):
    for y in range(0, len(yp)):
        zp[x][y] = xp[x]**2 + yp[y]**2


#-----------Plotting (single figure)---------------

map_proj = ccrs.PlateCarree(central_longitude = 6)


ax = salt_ocean1.plot(transform = ccrs.PlateCarree(),
                      subplot_kws={"projection":map_proj},
                      cmap = cm.haline,
                      add_colorbar=False)

ax2 = plt.contour(xp, yp, zp)

【问题讨论】:

  • 我不清楚你的情节现在是什么样子,以及你希望它是什么样子。您的代码示例很长,并且无法运行。我认为如果你能做一个非常小的、最小的例子——也许只是一个情节,那会很有帮助。并确保它会为复制/粘贴它的其他人运行。
  • 啊好吧!对不起,我会在早上这样做。谢谢

标签: python matplotlib plot contour


【解决方案1】:

您的示例等高线数据远离非洲海岸,因此我对其进行了一些更改,以使其位于您示例盐度数据的同一区域。 (也许您两次使用了示例“lons”,也用于“lats”?)

xp = np.arange(-3, 7, 2)
yp = np.arange(52, 62, 2)
xx, yy = np.meshgrid(xp, yp)
zp = (xx-xx.mean())**2 + (yy-yy.mean())**2

您可能只使用 xarray 中的绘图方法(它本身使用 Matplotlib)就可以得到您的结果。例如,请参阅文档中的“构面”部分:
http://xarray.pydata.org/en/stable/user-guide/plotting.html#faceting

我个人更喜欢直接使用 Matplotlib 创建图形和轴,然后使用 ax=ax 将要绘制的轴传递到 xarray。

map_proj = ccrs.PlateCarree(central_longitude=6)

fig, axs = plt.subplots(3,3, figsize=(10,9.5), constrained_layout=True, facecolor='w',
                        subplot_kw=dict(projection=map_proj))
axs = axs.ravel()

# loop over each axes
for i, ax in enumerate(axs, start=1):
    
    # set map extent
    ax.set_extent([-5, 10, 50, 65], crs=ccrs.PlateCarree())
    
    # add some cartopy features
    ax.coastlines(resolution='50m', alpha=.4)
    
    # Plot model data
    qm = salt_ocean1.plot(ax=ax, cmap=cm.haline, add_colorbar=False, transform=ccrs.PlateCarree())
    c = ax.contour(xp, yp, zp, levels=8, cmap='Blues', linewidths=2, transform=ccrs.PlateCarree())
    
    # do this after using xarray (it overrides the title)
    ax.set_title(f'model run: {i}')

# create 1 colorbar for all subplots using (ax=axs)
cb = fig.colorbar(qm, ax=axs, label='Salinity [g/kg]', shrink=.5)

请注意,使用transform=ccrs.PlateCarree() 会将地理投影分配给数据。对于与contour 一起使用的 Numpy 数组,这始终是必要的,因为它们没有任何元数据。我怀疑对于 xarray 数据集,它取决于可用的元数据,但是对于这个示例数据,它是必需的。但是,如果您的模型或测深数据具有不同的投影,则需要更改此投影。

cartopy 库中有很多示例展示了如何添加海岸线、土地、国家等任何特征:
https://scitools.org.uk/cartopy/docs/v0.13/gallery.html

【讨论】:

  • 太棒了!太感谢了!这确实帮助我了解了哪里出了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 2021-04-12
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多