前言

对于地学研究中,常见的就是画带有地图的空间场,在python中常用的就是基于basemap(好像停止更新了,不太确定)和cartopy(英国气象局开发,越来越完善)进行绘制,本文基于basemap介绍一些入门:画空间场以及多子图。

安装

几年前安装basemap是真的很麻烦,现在已经很简单了,直接一句话:

conda install basemap

主要依赖的绘图库

import matplotlib as mpl
from matplotlib.colors import LogNorm
from mpl_toolkits.basemap import Basemap, cm, shiftgrid, addcyclic
import matplotlib.pyplot as plt

可以直接使用的画图函数 (详细注释版)

这个函数可以直接使用,画每一个子图里面的空间场信息

def Plot2DForsubplots(data2D, lat, lon, DrawingNo, _reverse = True, defaultcamp = True):'''绘制 多子图空间场 ----------data2D: np.array, 2维变量数据 [lat,lon]lat: np.array, 1维, data2D相应的纬度信息lon: np.array, 1维, data2D相应的经度信息DrawingNo: str, 标号信息_reverse: 如果data2D的纬度是是从-90:90, 则需要将纬度反向, 变为90:-90-------'''t0Plot2D= time.time()print('*****************函数Plot2D开始*********************')if _reverse:data2D_plot = data2D[::-1, :]  # 纬度反向  画图要90:-90else:data2D_plot = data2D# 纬度反向  画图要90:-90# ========plot================# plt.subplots(figsize=(12, 8))mpl.rcParams['font.sans-serif'] = ['Times New Roman']  # 设置matplotlib整体用Times New Romanmpl.rcParams['font.weight'] = 'bold'  # 设置matplotlib整体用Times New Romanmpl.rcParams['font.size'] = 14  # 设置matplotlib整体用Times New Romanax = plt.gca()ax.yaxis.set_tick_params(labelsize=10.0)map = Basemap(projection='cyl', llcrnrlat=np.min(lat), urcrnrlat=np.max(lat), resolution='c',llcrnrlon=np.min(lon),urcrnrlon=np.max(lon))  # 所需的地图域(度)的左下角的经度 llcrnrlat The lower left corner geographical longitude# map.drawcoastlines(color='grey',linewidth=1)map.drawparallels(np.arange(-90, 91., 30.), labels=[True, False, False, True], fontsize=8,fontproperties='Times New Roman',color='grey', linewidth=0.5)  # 画平行线map.drawmeridians(np.arange(0., 360, 60), labels=[True, False, False, True], fontsize=8,fontproperties='Times New Roman',color='grey', linewidth=0.5)  # 在地图上画经线# map.readshapefile('/newshps/country1', 'country',#                   color='grey', linewidth=1)#map.fillcontinents(color='silver', zorder=1)map.etopo()  # 浮雕map.drawcoastlines()# ===========自定义color===============if defaultcamp:norm = mpl.colors.Normalize(vmin=-40, vmax=40)cax = plt.imshow(data2D_plot, cmap='seismic', extent=[np.min(lon), np.max(lon), np.min(lat), np.max(lat)], norm=norm,alpha=1)  # clim:色标范围 extent:画图经纬度区域   zorder:控制绘图顺序  vmin=data2D.max(), vmax=data2D.min(),else:#######==========自己设置colorbar间隔====================# mycolors = [(0.52941, 0.7, 1), (0.52941, 0.80784, 0.92157), (0.95,0.55,0.55), (0.98039, 0.50196, 0.44706), (0.99, 0.38824, 0.3),#             (1, 0.28, 0.28), (1, 0.15, 0.15), (1, 0, 0)]# my_cmap = mpl.colors.ListedColormap(mycolors)# clevs = [-12,-8,-6, -4, -2, 0, 2, 4, 6, 8, 10, 12]# print(my_cmap.N)# norm = mpl.colors.BoundaryNorm(clevs, my_cmap.N)# cax = plt.imshow(data2D_plot, cmap=my_cmap,#                  extent=[np.min(lon), np.max(lon), np.min(lat), np.max(lat)], norm=norm,#                  alpha=1)  # clim:色标范围 extent:画图经纬度区域   zorder:控制绘图顺序norm = mpl.colors.Normalize(vmin=-12, vmax=12)cax = plt.imshow(data2D_plot, cmap='seismic', extent=[np.min(lon), np.max(lon), np.min(lat), np.max(lat)], norm=norm, alpha=1)  # clim:色标范围 extent:画图经纬度区域   zorder:控制绘图顺序# =======添加图号===============plt.text(0, 91.5, DrawingNo, fontsize=12, fontproperties='Times New Roman')#plt.title(titles, fontsize=15, fontproperties='Times New Roman')# =======设置colorbar===============# cax = plt.axes([0.35, 0.28, 0.4, 0.02]) #前两个指的是相对于坐标原点的位置,后两个指的是坐标轴的长/宽度  这个设置的colorbar位置cbar = plt.colorbar()cbar.set_label('Temperature', fontsize=12, fontproperties='Times New Roman')ax.spines['bottom'].set_linewidth(2);  ###设置底部坐标轴的粗细ax.spines['left'].set_linewidth(2);  ####设置左边坐标轴的粗细ax.spines['right'].set_linewidth(2);  ###设置右边坐标轴的粗细ax.spines['top'].set_linewidth(2);  ###设置右边坐标轴的粗细print('***********************函数Plot2D结束, 耗时: %.3f s / %.3f mins****************' % ((time.time() - t0Plot2D), (time.time() - t0Plot2D) / 60))

完整脚本:

这个脚本是调用不断调用Plot2DForsubplots来实现画多子图,如果不需要画多子图,把循环去掉就行。

import os
import time
import code
import numpy as np
import pandas as pd
import xarray as xr
#=画图需要的包
import matplotlib as mpl
from matplotlib.colors import LogNorm
from mpl_toolkits.basemap import Basemap, cm, shiftgrid, addcyclic
import matplotlib.pyplot as pltdef Plot2DForsubplots(data2D, lat, lon, DrawingNo, _reverse = True, defaultcamp = True):'''绘制 多子图空间场----------data2D: np.array, 2维变量数据 [lat,lon]lat: np.array, 1维, data2D相应的纬度信息lon: np.array, 1维, data2D相应的经度信息DrawingNo: str, 标号信息_reverse: 如果data2D的纬度是是从-90:90, 则需要将纬度反向, 变为90:-90-------'''t0Plot2D= time.time()print('*****************函数Plot2D开始*********************')if _reverse:data2D_plot = data2D[::-1, :]  # 纬度反向  画图要90:-90else:data2D_plot = data2D# 纬度反向  画图要90:-90# ========plot================# plt.subplots(figsize=(12, 8))mpl.rcParams['font.sans-serif'] = ['Times New Roman']  # 设置matplotlib整体用Times New Romanmpl.rcParams['font.weight'] = 'bold'  # 设置matplotlib整体用Times New Romanmpl.rcParams['font.size'] = 14  # 设置matplotlib整体用Times New Romanax = plt.gca()ax.yaxis.set_tick_params(labelsize=10.0)map = Basemap(projection='cyl', llcrnrlat=np.min(lat), urcrnrlat=np.max(lat), resolution='c',llcrnrlon=np.min(lon),urcrnrlon=np.max(lon))  # 所需的地图域(度)的左下角的经度 llcrnrlat The lower left corner geographical longitude# map.drawcoastlines(color='grey',linewidth=1)map.drawparallels(np.arange(-90, 91., 30.), labels=[True, False, False, True], fontsize=8,fontproperties='Times New Roman',color='grey', linewidth=0.5)  # 画平行线map.drawmeridians(np.arange(0., 360, 60), labels=[True, False, False, True], fontsize=8,fontproperties='Times New Roman',color='grey', linewidth=0.5)  # 在地图上画经线# map.readshapefile('/home/tongxuan/newshps/country1', 'country',#                   color='grey', linewidth=1)#map.fillcontinents(color='silver', zorder=1)map.etopo()  # 浮雕map.drawcoastlines()# ===========自定义color===============if defaultcamp:norm = mpl.colors.Normalize(vmin=-40, vmax=40)cax = plt.imshow(data2D_plot, cmap='seismic', extent=[np.min(lon), np.max(lon), np.min(lat), np.max(lat)], norm=norm,alpha=1)  # clim:色标范围 extent:画图经纬度区域   zorder:控制绘图顺序  vmin=data2D.max(), vmax=data2D.min(),else:#######==========自己设置colorbar间隔====================# mycolors = [(0.52941, 0.7, 1), (0.52941, 0.80784, 0.92157), (0.95,0.55,0.55), (0.98039, 0.50196, 0.44706), (0.99, 0.38824, 0.3),#             (1, 0.28, 0.28), (1, 0.15, 0.15), (1, 0, 0)]# my_cmap = mpl.colors.ListedColormap(mycolors)# clevs = [-12,-8,-6, -4, -2, 0, 2, 4, 6, 8, 10, 12]# print(my_cmap.N)# norm = mpl.colors.BoundaryNorm(clevs, my_cmap.N)# cax = plt.imshow(data2D_plot, cmap=my_cmap,#                  extent=[np.min(lon), np.max(lon), np.min(lat), np.max(lat)], norm=norm,#                  alpha=1)  # clim:色标范围 extent:画图经纬度区域   zorder:控制绘图顺序norm = mpl.colors.Normalize(vmin=-12, vmax=12)cax = plt.imshow(data2D_plot, cmap='seismic', extent=[np.min(lon), np.max(lon), np.min(lat), np.max(lat)], norm=norm, alpha=1)  # clim:色标范围 extent:画图经纬度区域   zorder:控制绘图顺序# =======添加图号===============plt.text(0, 91.5, DrawingNo, fontsize=12, fontproperties='Times New Roman')#plt.title(titles, fontsize=15, fontproperties='Times New Roman')# =======设置colorbar===============# cax = plt.axes([0.35, 0.28, 0.4, 0.02]) #前两个指的是相对于坐标原点的位置,后两个指的是坐标轴的长/宽度  这个设置的colorbar位置cbar = plt.colorbar()cbar.set_label('Temperature', fontsize=12, fontproperties='Times New Roman')ax.spines['bottom'].set_linewidth(2);  ###设置底部坐标轴的粗细ax.spines['left'].set_linewidth(2);  ####设置左边坐标轴的粗细ax.spines['right'].set_linewidth(2);  ###设置右边坐标轴的粗细ax.spines['top'].set_linewidth(2);  ###设置右边坐标轴的粗细print('***********************函数Plot2D结束, 耗时: %.3f s / %.3f mins****************' % ((time.time() - t0Plot2D), (time.time() - t0Plot2D) / 60))def PlotTenYearAve():'''画CEMS2(第二版数据)和ERA5逐十年平均 多子图:return:'''#=加载数据Cesm2DataAnnual = np.load('/home/Cesm2DataAnnual.npy')#1950-2014   (65, 181, 359)  lat:-90:90 lon:0:360Era5DataAnnual = np.load('/home/ERA5DataAnnual.npy')#1950-2014    (65, 181,360)  lat:-90:90 lon:0:360LonLR = np.arange(0, 358.75, 1)LatLR = np.arange(-90, 90.5, 1)YearInterval = 10 #每十年画一张图DrawNo = ['(a)', '(b)', '(c)','(d)', '(e)', '(f)','(g)', '(h)', '(i)','(j)', '(k)', '(l)','(m)', '(n)', '(o)','(p)', '(q)', '(i)']fig = plt.figure(figsize=(25, 18))fig.subplots_adjust(wspace=0.05)for i in range((2014-1950)//10):Yeartitles = str(1950 + i * 10) + 's'Cesm2DataEach10Year = np.mean(Cesm2DataAnnual[i*YearInterval : (i+1)*YearInterval, :, :], axis=0) # (181, 359)  lat:-90:90 lon:0:358Era5DataEach10Year_ = np.mean(Era5DataAnnual[i * YearInterval: (i + 1) * YearInterval, :, :], axis=0)#(181,360)  lat:-90:90 lon:0:360Era5DataEach10Year = Era5DataEach10Year_[:Cesm2DataEach10Year.shape[0], :Cesm2DataEach10Year.shape[1]]# (181, 359)Cesm2_Era5Each10Year = Cesm2DataEach10Year - Era5DataEach10Yearplt.subplot((2014-1950)//10, 3, i * 3 + 1)Plot2DForsubplots(Cesm2DataEach10Year - 273.15, LatLR, LonLR, '%s CESM2 %s' % (DrawNo[i * 3 + 0],Yeartitles), _reverse=True, defaultcamp=True)plt.subplot((2014 - 1950) // 10, 3, i * 3 + 2)Plot2DForsubplots(Era5DataEach10Year - 273.15, LatLR, LonLR, '%s ERA5 %s' % (DrawNo[i * 3 + 1],Yeartitles), _reverse=True, defaultcamp=True)plt.subplot((2014 - 1950) // 10, 3, i * 3 + 3)Plot2DForsubplots(Cesm2_Era5Each10Year, LatLR, LonLR, '%s Difference %s' % (DrawNo[i * 3 + 2],Yeartitles), _reverse=True, defaultcamp=False)plt.savefig('/homeTenYearAve.jpg', dpi=600, bbox_inches='tight')if __name__ == "__main__":t0 = time.time()# ===================================================================================print('*****************程序开始*********************' )PlotTenYearAve()print('***********************程序结束, 耗时: %.3f s / %.3f mins****************' % ((time.time() - t0), (time.time() - t0) / 60))code.interact(local=locals())

效果展示

Python基于basemap画论文级别的多子图空间场相关推荐

  1. 【数据处理】 python 基于Basemap地理信息可视化

    数据   在某些建模比赛中,经常碰见一些地理信息的数据,它们大多都是车辆在驾驶过程中随时间产生的经纬度序列,并伴随着车辆的各种参数.由于GPS信号并不是一直都很好(如过隧道或偏远地区),无论建模的问题 ...

  2. Python下basemap画出的各种地图

    刚接触Python的basemap库时,被它所能产生的效果震撼了. 但是在深入的学习时发现网上很难找到系统的中文教程,仅能搜到一些博客文章里讲到的某些知识点,不成体系,就难以运用自如. 在网上看了看官 ...

  3. Python基于Django毕业设计论文选题系统设计

    技术环境: PyCharm + Django2.2 + Python3.7 + mysql 系统有三个身份:学生,教师和管理员.学生在网站前端可以查询班级信息,查询教师风采,可以查询某个老师开设的论文 ...

  4. python简单代码画曲线图教程-用Python画论文折线图、曲线图?几个代码模板轻松搞定!...

    前言 这几天在搞论文图,唉说实话抠图这种东西真能逼死人.坐在电脑前抠上一天越看越丑,最后把自己丑哭了-- 到了画折线图分析的时候,在想用哪些工具的时候.首先否决了excel,读书人的事,怎么能用exc ...

  5. python画折线图代码-用Python画论文折线图、曲线图?几个代码模板轻松搞定!

    前言 这几天在搞论文图,唉说实话抠图这种东西真能逼死人.坐在电脑前抠上一天越看越丑,最后把自己丑哭了-- 到了画折线图分析的时候,在想用哪些工具的时候.首先否决了excel,读书人的事,怎么能用exc ...

  6. matlab 折线图_用Python画论文折线图、曲线图?几个代码模板轻松搞定!

    前言 这几天在搞论文图,唉说实话抠图这种东西真能逼死人.坐在电脑前抠上一天越看越丑,最后把自己丑哭了-- 到了画折线图分析的时候,在想用哪些工具的时候.首先否决了excel,读书人的事,怎么能用exc ...

  7. 用Python画论文折线图、曲线图?几个代码模板轻松搞定!

    前言 这几天在搞论文图,唉说实话抠图这种东西真能逼死人.坐在电脑前抠上一天越看越丑,最后把自己丑哭了-- 到了画折线图分析的时候,在想用哪些工具的时候.首先否决了excel,读书人的事,怎么能用exc ...

  8. windows下python安装basemap,画世界地图以及根据经纬度标点

    环境安装 1.确定自己的python环境安装完毕且已配置好环境变量 2.安装geos:pip install geos 3.直接使用pip3 install pyproj 可能会安装错误,所以需要自己 ...

  9. Python 还原控制SCI论文算法系列1: 基于策略迭代的自适应最优控制器设计

    Python 还原控制SCI论文算法系列1: 基于策略迭代的自适应最优控制器设计 文章目录 Python 还原控制SCI论文算法系列1: 基于策略迭代的自适应最优控制器设计 0.前言 1.研究问题的描 ...

最新文章

  1. c#分布式ID生成器
  2. c# 连续抓取页面内容
  3. 概率统计笔记:高斯威沙特分布
  4. 【转】Android 轻松实现语音识别
  5. linux中的加法函数,上下文管理练习(为加法函数计时)
  6. dalvik虚拟机简单介绍
  7. linux下tmux
  8. 广外大全国计算机,广外全国计算机等级考试考生人数再创新高
  9. 阿里P9工程师指定面试复习资料
  10. Simscape Multibody 多体动力学仿真教程(一)
  11. 浙大 PAT 甲级 1077 Kuchiguse
  12. Hash 表的时间复杂度为什么是 O(1)(面试版)
  13. [转贴][教学] 教你如何打飞机 ^_^
  14. 增量式分级判别回归树(IHDR)|翻译与笔记
  15. 【LintCode 题解】小米面试算法题:搜索旋转排序数组
  16. wdk与DDK有什么区别
  17. python可以开发app吗-惊呆!那些顶级App居然是用Python开发的
  18. 基于WSL搭建ESP8266开发环境
  19. tp5 接收图片_TP5框架实现上传多张图片的方法分析
  20. 移动端app开发-03-IOS 初级开发入门教程

热门文章

  1. android rom包修改工具,自己修改安卓的ROM包(非官方) | 寒山烟雨
  2. 获取钉钉企业部门用户信息
  3. XML文档定义有几种方式?它们之间有何本质区别?解析XML文档有哪几种方式?
  4. Java线程状态及转换
  5. Java代码使用最小二乘法实现线性回归预测
  6. 初识linux之管道
  7. kubeflow--安装使用pipeline
  8. Hadoop的fsck工具
  9. 【Spring Boot JPA】ManyToOne OneToMany学习笔记
  10. 如何下载linux内核头文件,在Linux系统上安装Linux内核头文件的教程