matplotlib删除地图投影上的等值线及风场
【前言】最近在编写一个气象应用程序,用来显示某一时刻某一地区的气温等值线和风场,程序主要用到了第三方库matplotlib及Basemap。在编写的过程中发现,如果不进行擦除操作直接绘制新的等值线或风场,新的等值线(风场)会与原来的等值线(风场)叠加在一起,而绘制的等值线及风场没有单独的remove方法,所以如果想要擦除已经绘制的等值线就要将地图重新投影一遍,如果地图投影精度高一点,整个投影过程就会特别漫长。通过对等值线及风场的返回结果进行研究,我找到了一个不必重新投影地图就可将等值线及风场擦除的方法。
一、matplotlib及Basemap
matplotlib是Python常用的数据绘制包。它基于numpy的数组运算功能,可以轻易的画出各种统计图形,如散点图,条行图,饼图,等值线图等。Basemap是Matplotlib的一个子包,负责地图绘制。在数据可视化过程中,我们可以将数据在地图上画出来。
利用matplotlib及Basemap画图的基本步骤是:
创建一个figure实例
在figure里创建Axes容器实例
在Axes容器内创建Basemap实例进行地图投影
调用Basemap实例的contour及barbs方法进行在地图上绘图
二、不进行擦除操作直接绘制新的等值线或风场效果演示
为了方便演示,数据为我自己手中的数据,其中values,x1,y1为等值线的数据及坐标,huvalues,hvvalues,x2,y2为风场的数据及坐标,数据的格式及获得方法就不做过多解释
1.绘制地图投影
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
plt.show()
我们将得到下图演示的结果
2.绘制等值线
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
c=m.contour(x1,y1,values,15,linewidths=1.5)
plt.show()
得到结果如下:
3.继续绘制风场
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
c=m.contour(x1,y1,values,15,linewidths=1.5)
b=m.barbs(x2,y2,huvalues2.5,hvvalues2.5)
plt.show()
得到结果如下:
由此我们可以看出,如果在绘制新的等值线或者风场前不进行擦除操作,所有的图像都会叠加在一起
三、通过重新进行地图投影进行擦除操作
1.绘制地图投影
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
plt.show()
我们将得到下图演示的结果
2.绘制等值线
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
c=m.contour(x1,y1,values,15,linewidths=1.5)
plt.show()
得到结果如下:
3.擦除axes重新进行地图投影
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
x1,y1=m(lon,lat)
c=m.contour(x1,y1,values,15,linewidths=1.5)
ax.clear()
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
plt.show()
得到下图结果:
4.绘制风场
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
c=m.contour(x1,y1,values,15,linewidths=1.5)
ax.clear()
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
x2,y2=m(hulon,hulat)
b=m.barbs(x2,y2,huvalues2.5,hvvalues2.5)
plt.show()
得到结果如下:
此方法虽然可以达到预期的效果,但是我们的地图投影并未做过改变,重新进行地图投影毫无意义,而且还会占用系统不必要的资源
四、对等值线实例及风场实例进行研究
1.等值线
通过dir()命令我们可以查看创建的等值线实例c的属性方法
print(dir(c))
[''_A'',''__class__'',''__delattr__'',''__dict__'',''__dir__'',''__doc__'',''__eq__'',''__format__'',''__ge__'',''__getattribute__'',
''__getstate__'',''__gt__'',''__hash__'',''__init__'',''__le__'',''__lt__'',''__module__'',''__ne__'',''__new__'',''__reduce__'',
''__reduce_ex__'',''__repr__'',''__setattr__'',''__sizeof__'',''__str__'',''__subclasshook__'',''__weakref__'',''_add_label'',
''_auto'',''_autolev'',''_check_xyz'',''_contour_args'',''_contour_generator'',''_contour_level_args'',''_corner_mask'',
''_get_allsegs_and_allkinds'',''_get_label_clabeltext'',''_get_label_text'',''_get_lowers_and_uppers'',''_initialize_x_y'',
''_levels'',''_make_paths'',''_process_www.visa158.com_args'',''_process_colors'',''_process_levels'',''_process_linestyles'',''_process_linewidths'',
''_transform'',''add_checker'',''add_label'',''add_label_clabeltext'',''add_label_near'',''allkinds'',''allsegs'',''alpha'',''antialiased'',
''autoscale'',''autoscale_None'',''ax'',''calc_label_rot_and_inline'',''callbacksSM'',''changed'',''check_update'',''clabel'',''cmap'',
''collections'',''colorbar'',''colors'',''contour_doc'',''cvalues'',''extend'',''extent'',''filled'',''find_nearest_contour'',''get_alpha'',
''get_array'',''get_clim'',''get_cmap'',''get_label_coords'',''get_label_width'',''get_real_label_width'',''get_text'',''get_transform'',
''hatches'',''labelCValues'',''labelTexts'',''labels'',''layers'',''legend_elements'',''levels'',''linestyles'',''linewidths'',''locate_label'',
''locator'',''logscale'',''monochrome'',''nchunk'',''norm'',''origin'',''pop_label'',''print_label'',''set_alpha'',''set_array'',''set_clim'',
''set_cmap'',''set_label_props'',''set_norm'',''tcolors'',''tlinewidths'',''to_rgba'',''too_close'',''update_dict'',''vmax'',''vmin'',
''zmax'',''zmin'']
通过查看,发现在c的属性方法中并没有remove()方法,但是我们发现有一个属性是collections,这里的collections如果与Python的集合类相同,它就应该有remove()方法进删除,所以继续通过dir()命令进行查看
print(dir(c.collections)
[''__add__'',''__class__'',''__contains__'',''__delattr__'',''__delitem__'',''__dict__'',''__dir__'',''__doc__'',''__eq__'',
''__format__'',''__ge__'',''__getattribute__'',''__getitem__'',''__getstate__'',''__gt__'',''__hash__'',''__iadd__'',
''__imul__'',''__init__'',''__iter__'',''__le__'',''__len__'',''__lt__'',''__module__'',''__mul__'',''__ne__'',''__new__'',
''__reduce__'',''__reduce_ex__'',''__repr__'',''__reversed__'',''__rmul__'',''__setattr__'',''__setitem__'',
''__setstate__'',''__sizeof__'',''__str__'',''__www.hunanwang.net__'',''__subclasshook__'',''__weakref__'',''append'',''clear'',''copy'',
''count'',''extend'',''index'',''insert'',''pop'',''remove'',''reverse'',''sort'',''type'']
通过查看,发现c.collections有remove()方法,所以尝试用c.collections.remove()进行删除,由于remove()方法一次只能删除一个元素,所以要用for循环来进行删除。
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
c=m.contour(x1,y1,values,15,linewidths=1.5)
foriinc.collections:
i.remove()
plt.show()
得到下图结果:
由此可见,此方法可行
2.风场
通过dir()命令我们可以查看创建的等值线实例b的属性方法
print(dir(b))
[''__add__'',''__class__'',''__contains__'',''__delattr__'',''__dir__'',''__doc__'',''__eq__'',''__format__'',
''__ge__'',''__getattribute__'',''__getitem__'',''__getnewargs__'',''__gt__'',''__hash__'',''__init__'',
''__iter__'',''__le__'',''__len__'',''__lt__'',''__mul__'',''__ne__'',''__new__'',''__reduce__'',''__reduce_ex__'',
''__repr__'',''__rmul__'',''__setattr__'',''__sizeof__'',''__str__'',''__subclasshook__'',''count'',''index'']
可以发现风场的实例b没有remove方法,也没有collections属性,所以决定先通过type()方法看看风场实例是什么类型的
print(type(b))
可以发现风场实例b是一个元组,所以继续看它的元素有什么属性
print(dir(b[0]))
[''_A'',''__class__'',''__delattr__'',''__dict__'',''__dir__'',''__doc__'',''__eq__'',''__format__'',''__ge__'',''__getattribute__'',
''__getstate__'',''__gt__'',''__hash__'',''__init__'',''__le__'',''__lt__'',''__module__'',''__ne__'',''__new__'',''__reduce__'',
''__reduce_ex__'',''__repr__'',''__setattr__'',''__sizeof__'',''__str__'',''__subclasshook__'',''__weakref__'',''_agg_filter'',
''_alpha'',''_animated'',''_antialiaseds'',''_axes'',''_clipon'',''_clippath'',''_contains'',''_edgecolors'',
''_edgecolors_original'',''_facecolors'',''_facecolors_original'',''_factor'',''_find_tails'',''_get_bool'',
''_get_value'',''_gid'',''_hatch'',''_is_filled'',''_is_stroked'',''_label'',''_length'',''_linestyles'',''_linewidths'',
''_make_barbs'',''_mouseover'',''_offset_position'',''_offsets'',''_oid'',''_path_effects'',''_paths'',''_picker'',
''_pickradius'',''_pivot'',''_prepare_points'',''_propobservers'',''_rasterized'',''_remove_method'',
''_set_gc_clip'',''_sizes'',''_sketch'',''_snap'',''_stale'',''_transOffset'',''_transform'',''_transformSet'',
''_transforms'',''_uniform_offsets'',''_url'',''_urls'',''_visible'',''add_callback'',''add_checker'',''aname'',
''autoscale'',''autoscale_None'',''axes'',''barb_increments'',''barbs_doc'',''callbacksSM'',''changed'',
''check_update'',''clipbox'',''cmap'',''colorbar'',''contains'',''convert_xunits'',''convert_yunits'',''draw'',
''eventson'',''figure'',''fill_empty'',''findobj'',''flip'',''format_cursor_data'',''get_agg_filter'',''get_alpha'',
''get_animated'',''get_array'',''get_axes'',''get_children'',''get_clim'',''get_clip_box'',''get_clip_on'',
''get_clip_path'',''get_cmap'',''get_contains'',''get_cursor_data'',''get_dashes'',''get_datalim'',
''get_edgecolor'',''get_edgecolors'',''get_facecolor'',''get_facecolors'',''get_figure'',''get_fill'',''get_gid'',
''get_hatch'',''get_label'',''get_linestyle'',''get_linestyles'',''get_linewidth'',''get_linewidths'',
''get_offset_position'',''get_offset_transform'',''get_offsets'',''get_path_effects'',''get_paths'',''get_picker'',
''get_pickradius'',''get_rasterized'',''get_sizes'',''get_sketch_params'',''get_snap'',''get_transform'',
''get_transformed_clip_path_and_affine'',''get_transforms'',''get_url'',''get_urls'',''get_visible'',
''get_window_extent'',''get_zorder'',''have_units'',''hitlist'',''is_figure_set'',''is_transform_set'',
''mouseover'',''norm'',''pchanged'',''pick'',''pickable'',''properties'',''remove'',''remove_callback'',
''rounding'',''set'',''set_UVC'',''set_agg_filter'',''set_alpha'',''set_animated'',''set_antialiased'',''set_antialiaseds'',
''set_array'',''set_axes'',''set_clim'',''set_clip_box'',''set_clip_on'',''set_clip_path'',''set_cmap'',''set_color'',
''set_contains'',''set_dashes'',''set_edgecolor'',''set_edgecolors'',''set_facecolor'',''set_facecolors'',''set_figure'',
''set_gid'',''set_hatch'',''set_label'',''set_linestyle'',''set_linestyles'',''set_linewidth'',''set_linewidths'',''set_lw'',
''set_norm'',''set_offset_position'',''set_offsets'',''set_path_effects'',''set_paths'',''set_picker'',''set_pickradius'',
''set_rasterized'',''set_sizes'',''set_sketch_params'',''set_snap'',''set_transform'',''set_url'',''set_urls'',''set_verts'',
''set_verts_and_codes'',''set_visible'',''set_zorder'',''sizes'',''stale'',''stale_callback'',''to_rgba'',''u'',''update'',
''update_dict'',''update_from'',''update_scalarmappable'',''v'',''x'',''y'',''zorder'']
可以发现风场实例元组的元素自己就有remove属性,所以通过remove方法尝试一下可不可以进行风场的删除
importmatplotlib.pyplotasplt
frommpl_toolkits.basemapimportBasemap
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
m=Basemap(projection=''laea'',lon_0=90,lat_0=40,width=11000000,\
height=8000000,resolution=''l'',ax=ax)
m.drawcoastlines(color=''tan'')
b=m.barbs(x2,y2,huvalues2.5,hvvalues2.5)
foriinb:
i.remove()
plt.show()
得到下图结果:
由此可见,此方法可行
五、总结
对于等值线,可以通过等值线实例的collection属性的remove方法进行删除已经绘制等值线;对于风场,可以通过风场实例元组中个元素的remove方法进行删除已绘制风场;对于地图上其他绘图方法,也可以通过本文的方法进行一步步的尝试。
|
|