首页
学习
活动
专区
圈层
工具
发布
44 篇文章
1
机器学习需要掌握的九种工具!
2
PyAOS:大气和海洋科学Python社区
3
地球人工智能研究综述
4
优化物理和机器学习之间的协同作用
5
构建便于气象海洋应用的Anaconda环境(window版本)
6
Python结合Matlab气候数据工具箱CDT
7
用Python复现一篇Nature的研究: 1.数据下载及预处理
8
Python气象数据处理与绘图:相关性分析之散点图
9
Nature | 数据驱动的地球系统深度学习与过程理解
10
Python气象数据处理与绘图:常见的10种图像滤波方法
11
JAMES: 地球系统模式机器学习应用专刊
12
Python可视化 | xarray绘图样式配置
13
xarray系列|WRF模式前处理和后处理
14
Python可视化 | xarray一维数据绘图
15
构建适合大气与海洋应用的Anaconda环境
16
统计学中数据分析方法汇总!
17
Python可视化 | xarray 绘图时序图
18
深度学习 | 时序问题LSTM入门讲解
19
Python可视化 | xarray 二维绘图配色方案设置
20
MeteoInfoLab中如何将格点插值到站点?(附完整代码)
21
利用 pandas 和 xarray 整理气象站点数据
22
tensor与numpy数据类型转换
23
【机器学习基础】|交叉验证及Stacking
24
让数据动起来!用Python制作动画可视化效果,让数据不再枯燥!
25
数据处理 | EOF用法及可视化实例
26
数据处理 | 使用cfgrib加载GRIB文件
27
GISer如何学Python
28
数据下载 | NCEP再分析数据自动批量下载
29
关于滤波和NCL的filwgts_lanczos函数
30
数据处理 | xarray的计算距平、重采样、时间窗
31
数据处理 | xarray的NC数据基础计算(1)
32
基于Python的神经网络模型可视化绘图方法
33
python可视化 | 小波分析——​海温数据的时频域分解
34
Python精美地理可视化绘制
35
Python的常用库的数组定义及常用操作
36
Python可视化 | 温度、水深&CTRL向量空间分布图
37
python可视化 | contour、contourf、cartopy补充
38
NCL专辑 | 常用插值函数集锦
39
数值模式常用参数化方案简析及引用文献
40
数据处理与可视化 | 站点插值格点+空间区域掩膜
41
自动化工程 | 利用Python自动生成降雨量统计分析报告
42
图解NumPy:常用函数的内在机制
43
用手机运行你的Python代码
44
数据可视化 | 双Y轴可视化绘制方法(Python、R两种方法)

Python气象数据处理与绘图:相关性分析之散点图

1、前言

应粉丝要求更新一篇散点图相关分析的文章,这个图是否叫这个名字我也不太确定,考虑到这种图的画法大部分是使用散点的形式进行展示,那本文叫相关分析图吧。

很多文章中会提到2个变量之间有什么潜在联系的时候经常用的一张图就是散点图,比如说某地降水和温度之间是否存在联系,此时建立笛卡尔坐标系,横轴纵轴分别为降水和温度在同一位置随时间变化的量,这个时候在图中如果能看出来两者存在一些线性关系或者非线性的话,这个图就有价值了。说了这么多,我找几张图给大家看一下。

--降水和温度与动力之间的关系--

该图来自论文:Chen Z, Zhou T, Zhang L, et al. Global land monsoon precipitation changes in CMIP6 projections[J]. Geophysical Research Letters, 2020, 47(14): e2019GL086902.

图中还可以叠加相关系数的显著性检验,如果有多条模式或者不同时段进行对比的话可以在图中设置不同颜色的字体,比如上图使用的是不同时段的SSPs路径下CMIP6 MME结果来进行对比,目前学术上认为2021-2040为近期,2041-2060为中期,2080-2100为长期。这样的目的是为了看在未来不同时段下,CMIP6模式的结果是否呈现不同的特征,可以有一个横向的对比。

废话不多说了,开始吧~

2、读取数据

第一步,读入数据,代码如下

代码语言:javascript
复制
data=xarray.open_dataset('/mnt/d/science/large_ensemble/picture/Fig15.tas_gardient_sfc/scatter_tas_sfcwind_add_members.nc')
tas_gradient_NH=data.tas_gradient_nh.values
tas_gradient_SH=data.tas_gradient_sh.values
sfc_NH= (data.sfc_nh.values)
sfc_SH= (data.sfc_sh.values) #NH 的梯度需要反转
sfc_NH_full= (data.sfc_nh_full.values)
sfc_SH_full= (data.sfc_sh_full.values) #NH 的梯度需要反转
tas_gradient_NH_full= (data.tas_gradient_nh_full[:,1995-1950:].values)
tas_gradient_SH_full= (data.tas_gradient_sh_full[:,1995-1950:].values) 

这一步的话,不用太深究每个数据是什么意思。我在本篇文章中使用的数据是南北半球某区域的变量A和温度梯度在1950年到1995年的时间序列。也就是说A和温度对应的长度都是46,必须保证长度一致才能画图。这里可以这么理解: 平时时间序列图大家都画过了,x是Time,y是画的变量。这时候x和y的长度一致才能画图,散点图的话就是把x改为另一个长度相同的变量而已。

3、封装画图函数

封装函数是程序走向简洁性、易用性的重大一步,同时也是批量出图的一个关键点。后期会专门开一篇讲一下封装函数的一些注意点。

首先我们定义一个函数用来绘制图中的拟合一元线性方程

代码语言:javascript
复制
def f(x,intercept,trend):# 计算出拟合方程
    y=trend*x+intercept
    return y

然后我们定义散点图的函数

函数的步骤分别是计算散点图的线性趋势,通过linregress函数返回的数据计算拟合方程。然后通过personr函数计算出相关系数和进行显著性检验。最后把显著性检验的结果放到legend上面进行展示。

代码语言:javascript
复制
def draw_scatter(ax,x,y,label,color,linecolor,loc,bbox_to_anchor,):
    trend=np.zeros(2)
    intercept=np.zeros(2)
    p_value=np.zeros(2)
    trend[0], intercept[0], rsq1, p_value[0], std_err=stats.linregress(x,y)
    print("each 0.5 ℃ change of LTG over could cause a XX±XX m s-1=",0.5*trend[0],'sterr=',std_err)
    # 绘出图像
    CC=pearsonr(x, y)
    p=[]
    #if CC[1]<0.001:
    #    p="P<0.001"
    if CC[1]<0.1:
        p=r"$\it{P<0.01}$"
    if 0.1<=CC[1]<0.5:
        p=r"$\it{P<0.5}$"
    if CC[1]>=0.5:
        p="  "
    print("p=",p)
    ax.scatter(x,y,c = color,marker = '.', s=100) 
    ax.plot(x, f(x,intercept[0],trend[0]), color=linecolor, linewidth = 3,
            label=("$R$= %2.2f" %(CC[0])+", "  +p  ) 
           )
    ax.grid()
    leg=ax.legend(loc=loc,prop={'size':20},frameon=False,
                 handlelength=0,
                  bbox_to_anchor=bbox_to_anchor
                 )
    ax.tick_params(labelsize=17)
    ax.minorticks_on()
    ax.tick_params(which='major', width=1.5)
    ax.tick_params(which='major', width=1.0)
    ax.tick_params(which='major', length=9)
    ax.tick_params(which='minor', length=6)
    ax.set_ylabel('Precipitation anomaly ', loc='center' ,   fontsize =20,labelpad=12)
    ax.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))# 保留2位小数点
    return ax

这个图传递的参数比较多,ax是创建的图层,x和y是散点图的x和y轴对应的数据,后面2个color是散点和线的颜色,loc是legend的位置,bbox是自定义位置相对于loc而已。有同学会说怎么这么复杂呢。其实函数复杂一点的话对很多图自定义来说反而简单了,这样可以增加后期修改图时的麻烦,也可以高度自定义化,形成自己的画图风格。我建议大家对函数要真正理解清楚每一句话的意义,这样才能达到随心所欲的境界。

4、画图

画图的代码就是添加fig和ax,不使用subplot,这一步可以参考:

Python气象数据处理与绘图:更自由的多子图组图绘制

好了,代码奉上:

代码语言:javascript
复制
fig_31 =plt.figure(figsize=(6, 5),dpi=60)
ax0 =fig_31.add_axes([1.4, 6.3,  0.9, 0.9])
ax1 =fig_31.add_axes([2.6, 6.3,  0.9, 0.9])
bbox_to_anchor1=(0.8,0.95)
bbox_to_anchor2=(0.2,0.95)
draw_scatter(ax0,tas_gradient_NH,sfc_NH," ",'orange',"black",
                                  'upper right',(1.01,1))
draw_scatter(ax1,tas_gradient_SH,sfc_SH," ", 'lime',"black",
                                  'upper left',(0.00,1))
ax0.invert_xaxis()
ax0.set_title('Northern Hemisphere ',loc='right',fontsize =22)
ax1.set_title('Southern Hemisphere ',loc='right',fontsize =22)
ax0.set_title('(c)',loc='left',fontsize =24)
ax1.set_title('(d)',loc='left',fontsize =24)
ax1.set_xlabel('Air temperature gradient increase :$^\circ$C ', loc='center' ,  fontsize =20,labelpad=12)
ax0.set_xlabel('Air temperature gradient decrease:$^\circ$C ', loc='center' ,  fontsize =20,labelpad=12)

出图效果如下:

图片画出来后就是看图说话,比如说a图中,我们可以看到北半球的变量A和温度梯度之间呈现明显的正相关,由于温度梯度在南北半球的方向相反,所以我把a图的温度梯度进行了反转,这样更加有利于理解。其他的同学要具体问题具体分析,这里要学会修改代码。a图中相关系数为0.88,P<0.01,这个结果显示出很强的相关性,并且通过线性回归方程的表现来看,基本呈现线性相关。从b图中也可以看到差不多的结果,但是b图中的相关系数更高,所以从图的整体可以得到结论:A变量与温度梯度的相关性很高,其中南半球A与温度梯度变化更为密切相关。

下一篇
举报
领券