简体   繁体   English

使用底图和Matplotlib绘制时间序列轮廓数据

[英]Plotting timeseries contour data with basemap and matplotlib

I'm new to basemap and python but I'm trying to build a plotter for weather model for daily cron job. 我是底图和python的新手,但我正在尝试为日常cron工作构建用于天气模型的绘图仪。 We plot about 1000 images a day. 我们每天绘制约1000张图像。

I've wrote some script to achieve what i want. 我已经写了一些脚本来实现我想要的。 But it took very long time, because it re-draw the basemap for every time-step. 但是,这花费了很长时间,因为它会为每个时间步骤重新绘制底图。 It took 30 seconds to draw the basemap, and only took 4 seconds to draw the contourf(). 绘制底图只花了30秒钟,而绘制轮廓线f()只花了4秒钟。

I have some idea to speed up the process by pre-draw the basemap and update the contourf() in each iteration. 我有一些想法,可以通过预先绘制底图并在每次迭代中更新outlinef()来加快过程。 But i don't understand how matplotlib objects work. 但是我不明白matplotlib对象是如何工作的。

I have researched for the same question about this but haven't found any. 我已经对此进行了研究,但没有找到任何问题。 But I found something similar from here from user3982706. 但我发现从类似的东西在这里从user3982706。

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()

That script save the contour data as a list of artist. 该脚本将轮廓数据保存为艺术家列表。 I don't need animation. 我不需要动画。 so I need to edit this script to save the figure inside the loop. 所以我需要编辑此脚本以将图保存在循环中。 So this script produce figure1.png, figure2.png, figure3.png, and so on. 因此,此脚本会产生fig1.png,figure2.png,figure3.png等。

Any suggestion? 有什么建议吗?

(a) Using animation to save images (a)使用动画保存图像

Because you already have the animation present in the code, you may directly save each image of the animation via the ani.save command. 由于代码中已经包含动画,因此可以通过ani.save命令直接保存动画的每个图像。

ani.save("figure.png", writer="imagemagick")

This will create 20 figures called figure-0.png to figure-19.png . 这将创建20个图,称为figure-0.pngfigure-19.png It requires imagemagick to be installed and available in your environment. 它需要安装imagemagick并在您的环境中可用。

(b) Save individual figures (b)保存个人数字

If the above fails for whatever reason, you may save the individual figures via plt.savefig() . 如果以上原因导致失败,则可以通过plt.savefig()保存单个图形。 At the end of each loop step, you would then remove the artists from the axes and delete them. 在每个循环步骤的最后,您需要从轴上删除艺术家并删除它们。

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM