使用底图和 matplotlib 绘制时间序列等高线数据
Plotting timeseries contour data with basemap and matplotlib
我是底图新手,python 但我正在尝试为每日 cron 作业构建天气模型绘图仪。我们每天绘制大约 1000 张图像。
我写了一些脚本来实现我想要的。但它花了很长时间,因为它会为每个时间步重新绘制底图。画底图用了30秒,画contourf()只用了4秒
我有一些想法可以通过预绘制底图并在每次迭代中更新 contourf() 来加快该过程。但我不明白 matplotlib 对象是如何工作的。
我已经研究过关于这个的相同问题,但没有找到。但是我从 user3982706 的 here 中找到了类似的东西。
from matplotlib import animation
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
fig, ax = plt.subplots()
# set up map projection
m = Basemap(projection='nsper',lon_0=-0,lat_0=90)
m.drawcoastlines()
m.drawparallels(np.arange(0.,180.,30.))
m.drawmeridians(np.arange(0.,360.,60.))
# some 2D geo arrays to plot (time,lat,lon)
data = np.random.random_sample((20,90,360))
lat = np.arange(len(data[0,:,0]))
lon = np.arange(len(data[0,0,:]))
lons,lats = np.meshgrid(lon,lat)
# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are animating three artists, the contour and 2
# annotatons (title), in each frame
ims = []
for i in range(len(data[:,0,0])):
im = m.contourf(lons,lats,data[i,:,:],latlon=True)
add_arts = im.collections
text = 'title={0!r}'.format(i)
te = ax.text(90, 90, text)
an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction')
ims.append(add_arts + [te,an])
ani = animation.ArtistAnimation(fig, ims)
## If you have ffmpeg you can save the animation by uncommenting
## the following 2 lines
# FFwriter = animation.FFMpegWriter()
# ani.save('basic_animation.mp4', writer = FFwriter)
plt.show()
该脚本将轮廓数据保存为艺术家列表。我不需要动画。所以我需要编辑这个脚本来保存循环中的图形。所以这个脚本会产生 figure1.png、figure2.png、figure3.png 等等。
有什么建议吗?
(a) 使用动画保存图片
因为代码中已经有了动画,所以可以通过ani.save
命令直接保存动画的每个图像。
ani.save("figure.png", writer="imagemagick")
这将创建 20 个名为 figure-0.png
到 figure-19.png
的图形。它需要安装 imagemagick 并在您的环境中可用。
(b) 保存个人数字
如果上述方法因任何原因失败,您可以通过plt.savefig()
保存个人数字。在每个循环步骤结束时,您将从坐标区中移除艺术家并将其删除。
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
fig, ax = plt.subplots()
m = Basemap(projection='nsper',lon_0=-0,lat_0=90)
m.drawcoastlines()
m.drawparallels(np.arange(0.,180.,30.))
m.drawmeridians(np.arange(0.,360.,60.))
data = np.random.random_sample((20,90,360))
lat = np.arange(len(data[0,:,0]))
lon = np.arange(len(data[0,0,:]))
lons,lats = np.meshgrid(lon,lat)
for i in range(len(data[:,0,0])):
im = m.contourf(lons,lats,data[i,:,:],latlon=True)
text = 'title={0!r}'.format(i)
te = ax.text(90, 90, text)
an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction')
# save the figure
plt.savefig("figure_{}.png".format(i))
# remove stuff from axes
for c in im.collections:
c.remove()
te.remove()
an.remove()
del im; del te; del an
plt.show()
我是底图新手,python 但我正在尝试为每日 cron 作业构建天气模型绘图仪。我们每天绘制大约 1000 张图像。
我写了一些脚本来实现我想要的。但它花了很长时间,因为它会为每个时间步重新绘制底图。画底图用了30秒,画contourf()只用了4秒
我有一些想法可以通过预绘制底图并在每次迭代中更新 contourf() 来加快该过程。但我不明白 matplotlib 对象是如何工作的。
我已经研究过关于这个的相同问题,但没有找到。但是我从 user3982706 的 here 中找到了类似的东西。
from matplotlib import animation
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
fig, ax = plt.subplots()
# set up map projection
m = Basemap(projection='nsper',lon_0=-0,lat_0=90)
m.drawcoastlines()
m.drawparallels(np.arange(0.,180.,30.))
m.drawmeridians(np.arange(0.,360.,60.))
# some 2D geo arrays to plot (time,lat,lon)
data = np.random.random_sample((20,90,360))
lat = np.arange(len(data[0,:,0]))
lon = np.arange(len(data[0,0,:]))
lons,lats = np.meshgrid(lon,lat)
# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are animating three artists, the contour and 2
# annotatons (title), in each frame
ims = []
for i in range(len(data[:,0,0])):
im = m.contourf(lons,lats,data[i,:,:],latlon=True)
add_arts = im.collections
text = 'title={0!r}'.format(i)
te = ax.text(90, 90, text)
an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction')
ims.append(add_arts + [te,an])
ani = animation.ArtistAnimation(fig, ims)
## If you have ffmpeg you can save the animation by uncommenting
## the following 2 lines
# FFwriter = animation.FFMpegWriter()
# ani.save('basic_animation.mp4', writer = FFwriter)
plt.show()
该脚本将轮廓数据保存为艺术家列表。我不需要动画。所以我需要编辑这个脚本来保存循环中的图形。所以这个脚本会产生 figure1.png、figure2.png、figure3.png 等等。
有什么建议吗?
(a) 使用动画保存图片
因为代码中已经有了动画,所以可以通过ani.save
命令直接保存动画的每个图像。
ani.save("figure.png", writer="imagemagick")
这将创建 20 个名为 figure-0.png
到 figure-19.png
的图形。它需要安装 imagemagick 并在您的环境中可用。
(b) 保存个人数字
如果上述方法因任何原因失败,您可以通过plt.savefig()
保存个人数字。在每个循环步骤结束时,您将从坐标区中移除艺术家并将其删除。
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
fig, ax = plt.subplots()
m = Basemap(projection='nsper',lon_0=-0,lat_0=90)
m.drawcoastlines()
m.drawparallels(np.arange(0.,180.,30.))
m.drawmeridians(np.arange(0.,360.,60.))
data = np.random.random_sample((20,90,360))
lat = np.arange(len(data[0,:,0]))
lon = np.arange(len(data[0,0,:]))
lons,lats = np.meshgrid(lon,lat)
for i in range(len(data[:,0,0])):
im = m.contourf(lons,lats,data[i,:,:],latlon=True)
text = 'title={0!r}'.format(i)
te = ax.text(90, 90, text)
an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction')
# save the figure
plt.savefig("figure_{}.png".format(i))
# remove stuff from axes
for c in im.collections:
c.remove()
te.remove()
an.remove()
del im; del te; del an
plt.show()