• matplotlib删除地图投影上的等值线及风场


    【前言】最近在编写一个气象应用程序,用来显示某一时刻某一地区的气温等值线和风场,程序主要用到了第三方库matplotlib及Basemap。在编写的过程中发现,如果不进行擦除操作直接绘制新的等值线或风场,新的等值线(风场)会与原来的等值线(风场)叠加在一起,而绘制的等值线及风场没有单独的remove方法,所以如果想要擦除已经绘制的等值线就要将地图重新投影一遍,如果地图投影精度高一点,整个投影过程就会特别漫长。通过对等值线及风场的返回结果进行研究,我找到了一个不必重新投影地图就可将等值线及风场擦除的方法。

    一、matplotlib及Basemap

    matplotlib是Python常用的数据绘制包。它基于numpy的数组运算功能,可以轻易的画出各种统计图形,如散点图,条行图,饼图,等值线图等。
    Basemap是Matplotlib的一个子包,负责地图绘制。在数据可视化过程中,我们可以将数据在地图上画出来。

    利用matplotlib及Basemap画图的基本步骤是:

    1. 创建一个figure实例
    2. 在figure里创建Axes容器实例
    3. 在Axes容器内创建Basemap实例进行地图投影
    4. 调用Basemap实例的contour及barbs方法进行在地图上绘图

    二、不进行擦除操作直接绘制新的等值线或风场效果演示

    为了方便演示,数据为我自己手中的数据,其中values,x1,y1为等值线的数据及坐标,huvalues,hvvalues,x2,y2为风场的数据及坐标,数据的格式及获得方法就不做过多解释

    1. 绘制地图投影

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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. 绘制等值线

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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. 继续绘制风场

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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,huvalues*2.5,hvvalues*2.5)
    plt.show()
    

    得到结果如下:

    由此我们可以看出,如果在绘制新的等值线或者风场前不进行擦除操作,所有的图像都会叠加在一起

    三、通过重新进行地图投影进行擦除操作

    1. 绘制地图投影

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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. 绘制等值线

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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重新进行地图投影

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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. 绘制风场

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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,huvalues*2.5,hvvalues*2.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_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__', '__subclasshook__', '__weakref__', 'append', 'clear', 'copy',
     'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort', 'type']
    

    通过查看,发现c.collectionsremove()方法,所以尝试用c.collections.remove()进行删除,由于remove()方法一次只能删除一个元素,所以要用for循环来进行删除。

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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)
    for i in c.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))
    <class 'tuple'>
    

    可以发现风场实例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方法尝试一下可不可以进行风场的删除

    import matplotlib.pyplot as plt
    from mpl_toolkits.basemap import Basemap
    
    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,huvalues*2.5,hvvalues*2.5)
    for i in b:
        i.remove()
    plt.show()
    

    得到下图结果:

    由此可见,此方法可行

    五、总结

    对于等值线,可以通过等值线实例的collection属性的remove方法进行删除已经绘制等值线;
    对于风场,可以通过风场实例元组中个元素的remove方法进行删除已绘制风场;
    对于地图上其他绘图方法,也可以通过本文的方法进行一步步的尝试。


    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    想观看Matplotlib教学视频,了解更多Matplotlib实用技巧可关注

    微信公众账号: MatplotlibClass

    今日头条号:Matplotlib小讲堂

  • 相关阅读:
    Microsoft .NET Framework 2.0实现发送邮件(Email)总结
    Microsoft .NET Framework 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)实现汇总
    抽象类
    WingIDE 单步调试 Uliweb Python 代码
    Android 4.0 SDK的离线方式安装
    .NET 3.5 中WCF客户端代理性能改进以及最佳实践
    在linux上部署Redmine
    认识jQuery mobile 框架,资源,书籍
    如何使用搜索技巧来成为一名高效的程序员
    Management Console 工具管理类软件通用开发框架(开放源码)
  • 原文地址:https://www.cnblogs.com/kallan/p/5867484.html
Copyright © 2020-2023  润新知