【跟着SCI学作图】Python matplotlib绘制带有边界的散点图

【跟着SCI学作图】Python matplotlib绘制带有边界的散点图

前段时间看文献【Smartforests Canada: A Network of Monitoring Plots for Forest Management Under Environmental Change】看到了这么一幅图,可以展示不同森林区域的气温降水数据,并且还可以展示站点数据。由此想借鉴模仿一下。
在这里插入图片描述
由于无法获取文中数据,本例运用ERA5气象数据,和中科院的森林类型数据;并根据城市经纬度提取ERA5数据模拟站点数据。
最终结果如下:
在这里插入图片描述
代码如下,详见代码注释:

# -*- encoding: utf-8 -*-
'''
@File    :   prep_temp.py
@Time    :   2022/05/12 10:23:43
@Author  :   HMX 
@Version :   1.0
@Contact :   kzdhb8023@163.com
'''

# here put the import lib
import matplotlib as mpl
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from osgeo import gdal
from scipy.spatial import ConvexHull
import alphashape
from descartes import PolygonPatch
import matplotlib.colors as colors



def tif2arr(tif):
    ds = gdal.Open(tif)
    arr = ds.ReadAsArray().flatten()
    return arr


def pplot(data,ls='-',ec = 'k',label='label'):
    points = data.iloc[:,:-1].values
    alpha_shape = alphashape.alphashape(points,0)
    ax.add_patch(PolygonPatch(alpha_shape, alpha=1,fc = 'none',ec = ec,linestyle = ls,label = label))


def ExValues2Points(tif,df):
    arr = []
    dr = gdal.Open(tif)
    transform = dr.GetGeoTransform()
    x_origin = transform[0]
    y_origin = transform[3]
    pixel_width = transform[1]
    pixel_height = transform[5]
    for i in range(len(df)):
        x = df['经度'].values[i]
        y = df['纬度'].values[i]
        x_offset = int((x - x_origin) / pixel_width)
        y_offset = int((y - y_origin) / pixel_height)
        dt = dr.ReadAsArray()[x_offset, y_offset]
        arr.append(dt)
    return arr


size1 = 10.5
fontdict = {'weight': 'bold','size':size1,'family':'SimHei'}
mpl.rcParams.update(
    {
    'text.usetex': False,
    'font.family': 'stixgeneral',
    'mathtext.fontset': 'stix',
    "font.family":'serif',
    "font.size": size1,
    "font.serif": ['Times New Roman'],
    }
    )


# 数据读取
prep= r"E:\Project\CODE\Other\Zwenyi\data\ex\EXprep.tif"
temp= r'E:\Project\CODE\Other\Zwenyi\data\ex\EXtemp2020_07.tif'
lcpt= r'E:\Project\CODE\Other\Zwenyi\data\LC\Exmerge_Resample.tif'

df = pd.DataFrame({'tt':tif2arr(temp),'pp':tif2arr(prep),'lc':tif2arr(lcpt)})
nvlist = df.iloc[0,:]
for i in range(len(nvlist)):
    df = df[df.iloc[:,i] != nvlist[i]]
df.tt = df.tt-272.15
res = df[(df.lc>=1)&(df.lc<=5)]


fig,ax = plt.subplots(1,1,figsize = (8,6))
im = plt.hexbin(res.tt,res.pp,gridsize=20,mincnt=1,cmap = 'plasma_r')
ax.set_xlabel('TEMP/℃')
ax.set_ylabel('PREP/mm')
ax.set_title('西南地区不同林型气温降水图',fontdict=fontdict,fontsize = 18)
ax.set_xlim(5,30)
ax.set_ylim(500,4000)
cb = plt.colorbar()
cb.set_label('Count',fontsize = 10.5)

# 森林类型数据获取
res1 = df[df.lc==1]
res2 = df[df.lc==2]
res3 = df[df.lc==3]
res4 = df[df.lc==4]
res5 = df[df.lc==5]

# 森林类型外框绘制
pplot(res1,ls = ':',label = '灌木林')
pplot(res2,ls = '--',label = '季风雨林')
pplot(res3,ls = '-',label = '常绿阔叶林')
pplot(res4,ls = '-.',label = '常绿针叶林')
pplot(res5,ls = (0, (8, 10)),label = '混交林')

# 站点数据的获取
dfstd = pd.read_excel(r'E:\Project\CODE\Other\Zwenyi\data\station\xinan.xlsx',header=0)#读取站点经纬度
std = pd.DataFrame({'prep':ExValues2Points(prep,dfstd),'temp':ExValues2Points(temp,dfstd)})
std.temp = std.temp-272.15
std = std.round(2)
std = pd.concat([dfstd,std],axis=1)

# 绘制站点
clist = ['k','b','r','g']
for i in range(len(std)):
    plt.scatter(std.temp.values[i],std.prep.values[i],marker='o',facecolor = clist[i],edgecolors='k',s = 100,label = std['省会'].values[i])
ax.legend(prop = fontdict)
plt.tight_layout()
plt.savefig('pt.png',dpi = 600)
plt.show()

如果对你有帮助的话,请‘点赞’、‘收藏’,‘关注’,你们的支持是我更新的动力。欢迎关注我的公众号【森气笔记】。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值