python - 在 Python 中调用其他函数来制作子图

标签 python loops matplotlib plot subplot

更新:我现在可以在正确的位置获得子图并显示正确的数据!但是,还有一个问题,那就是我无法为子图提供自己的标题和颜色条。实际上,我宁愿在所有图的右侧只有一个颜色条,但这似乎也不起作用。这是我的新代码以及一些示例数据(非常缺乏洞察力,但仅用于测试目的):

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import cartopy.crs as ccrs

lons = np.arange(-180,180,1)
lats = np.arange(-80,80,1)
dens = np.zeros((12, len(lons), len(lats)))
for i in range(12):
   dens[i,:,:] = i

def plotTitle(yr):
   letter = chr(yr-2002+97)
   return '(' + letter + ') ' + str(yr)

def DensityPlot(yr, lon, lat, dens, ax):
   Lat, Lon = np.meshgrid(lat, lon)
   density = ax.pcolormesh(Lon, Lat, dens, cmap = 'jet')
   #cbar = ax.colorbar(density, orientation='vertical', shrink=0.5, extend='both') # this gives an error: ''GeoAxesSubplot' object has no attribute 'colorbar''
   ax.coastlines()
   plt.title(plotTitle(yr),fontsize=14,fontweight='bold') # this only works for the last plot. ax.title doesn't work, gives the error ''Text' object is not callable'

fig, axes = plt.subplots(nrows=6, ncols=2, figsize=(35,35), subplot_kw={'projection': ccrs.PlateCarree()}) ## check figsize
i=0
for ax in axes.flat:
   densdata = dens[i,:,:]
   density = DensityPlot(i+2002, lons, lats, densdata, ax)
   i=i+1
   #ax.title(plotTitle(i+2002)) # this gives the same error as mentioned before: ''Text' object is not callable'
#cbar = plt.colorbar(density, orientation='vertical', shrink=0.5, extend='both')
# this gives the following RuntimeError: No mappable was found to use for colorbar creation. First define a mappable such as an image (with imshow) or a contour set (with contourf).
fig.subplots_adjust(right=0.5)

如何确保每个子图都有自己的标题,并且所有子图旁边都有一个颜色条?


我在用 Python 创建一组子图时遇到了问题。我已经定义了一个生成特定图的函数:

def DensityPlot(lon, lat, dens):
   Lat, Lon = np.meshgrid(lat, lon)
   fig = plt.figure(figsize=(12,12))
   ax = plt.axes(projection=ccrs.PlateCarree())
   density = plt.pcolormesh(Lon, Lat, dens, cmap = 'jet')
   cbar = plt.colorbar(orientation='vertical', shrink=0.5, extend='both')
   cbar.set_label("Plastic Density ($10^{-3}$ particles km$^{-2}$)", rotation=90,fontsize=12)
   ax.coastlines()
   return density

现在我想在 for 循环中使用这个函数来生成子图。为简单起见,假设我可以在每个子图中为 latlondens 使用相同的值(这样我就会得到相同的图多次)。然而,下面的代码不起作用:

fig, axes = plt.subplots(nrows=6, ncols=2)
for j in range(0,12): 
   plt.subplot(6,2,j+1)
   density = DensityPlot(lon, lat, dens)

发生了以下事情:首先,显示了 12 个空图,尽管它们的顺序是正确的 (6x2)。之后,11 个空地 block 出现在彼此下方,最后最后一个地 block 实际显示为应有的显示方式。我已经检查了函数 DensityPlot 的代码以仅创建单个图并且知道它可以正常工作,因此问题一定出在子图创建中。这可能是什么问题,我该如何解决?

最佳答案

您自己怀疑,您是在循环外创建子图,但每次调用您的函数时都会创建一个新图形。

您应该首先使用所需的投影创建图形和坐标轴:

fig, axes = plt.subplots(nrows=6, ncols=2, subplot_kw={'projection': ccrs.PlateCarree()})

然后您可以遍历轴,并将其作为参数传递给您的函数(确保删除图形本身中的任何图形或轴创建):

def DensityPlot(lon, lat, dens, ax):
   Lat, Lon = np.meshgrid(lat, lon)
   density = ax.pcolormesh(Lon, Lat, dens, cmap = 'jet')
   cbar = ax.colorbar(orientation='vertical', shrink=0.5, extend='both')
   cbar.set_label("Plastic Density ($10^{-3}$ particles km$^{-2}$)", rotation=90,fontsize=12)
   ax.coastlines()

   return density

for ax in axes.flat:
    density = DensityPlot(lon, lat, dens, ax)

为了给每个子图添加标题,您需要在函数中使用 ax.set_title():

ax.set_title(plotTitle(yr))

关于为多个子图添加颜色条还有很多其他问题。例如Matplotlib 2 Subplots, 1 Colorbar

关于python - 在 Python 中调用其他函数来制作子图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52668309/

相关文章:

jquery添加子元素属性

python - matplotlib:将轴偏移值格式化为整数或特定数字

python - 如何让我的 Cartopy 颜色条具有我设置的特定范围?

python - Python 的迭代器解包(star unpacking)是如何实现的(或者说,解包自定义迭代器涉及哪些神奇的方法?)

python - "ValueError: The truth value of an array with more than one element is ambiguous"

python - 根据文件名创建文件夹

vba - 在避免循环的范围内更改值,以提高速度

java - 更好的 Java 循环?

python条形图条形上的总标签

Python 名称阴影混淆