前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >气象绘图加强版(二)——散点图

气象绘图加强版(二)——散点图

作者头像
气象学家
发布2020-07-01 15:00:16
1.9K0
发布2020-07-01 15:00:16
举报
文章被收录于专栏:气象学家气象学家

本节提要:接着上一章折线图,简要谈谈散点图scatter( )的常用关键参数,以及在气象绘图上的简单应用。

一、简要谈谈散点图

散点图scatter在气象绘图上主要用于地理信息的标注、站点值的检验、时间序列数据可视化等等,相比其他行业,气象上散点图的应用明显低频。当散点图的直径大小和内部填色改变时,有一个名谓“气泡图”的说法。

下面是在文献中截取的两种典型使用方式:

图一 使用散点图表示青藏高原站点地理信息

图二 使用散点图表示站点突变信息

二、scatter( )绘图函数的基础运作

在前一章我们已经提到过,plot函数在某些时候可以简单理解为将scatter函数的散点连接起来,所以,其基础绘制方式也是依靠横轴、纵轴数据来确定散点在笛卡尔坐标系中的位置,并绘图。然后,依靠其关键字参数来进行修饰美化。

scatter( )函数的传入数据方式可参考plot( ),注意x、y数组长度必须一致。

三、scatter( )函数的常用关键字参数

scatter( )函数的核心部分当然是围绕着修饰散点进行,也匹配一定的其他修改命令。下面简要介绍常用scatter关键字命令。

scatter( )函数常用关键字参数

xy

传入scatter( )的横纵轴数据,用于确定散点位置

s

控制散点的大小

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']#中文正常显示
def sample_data():#编制实验数据
    x=range(1,21)#横坐标数据
    y=np.array([2,4,6,7,5,3,3,5,7,9,1115,10,8,4,7,8,3,2,5,7])#纵坐标数据
    data1=np.array([22,13,24,26,30,31,36,20,27,15,17,19,24,27,30,15,21,22,10,27])
    data2=np.array([120,132,143,151,109,149,125,119,120,158,171,101,106,108,126,149,127,151,143,102])
    return x,y,data1,data2
x,y,data1,data2=sample_data()#获得实验数据
fig=plt.figure(figsize=(2.5,2),dpi=500)
ax1=fig.add_axes([0,0,1,0.45])
ax2=fig.add_axes([0,0.55,1,0.45])
ax1.scatter(x,y,s=20,zorder=2)
ax2.scatter(x,y,s=50,zorder=2)
ax1.set(xlim=(0,21),ylim=(1,15))
ax2.set(xlim=(0,21),ylim=(1,15))
ax1.tick_params(axis='both',direction='in',length=3,width=0.5,labelsize=7)
ax2.tick_params(axis='both',direction='in',length=3,width=0.5,labelsize=7)
ax1.grid(alpha=0.75,ls=':')
ax2.grid(alpha=0.75,ls=':')

c

控制散点颜色

代码语言:javascript
复制
ax1.scatter(x,y,c='tab:green',zorder=2)
ax2.scatter(x,y,c='tab:blue',zorder=2)

marker

指定散点样式

代码语言:javascript
复制
ax1.scatter(x,y,marker='*',zorder=2)
ax2.scatter(x,y,marker='s',zorder=2)

cmap

与c参数配合,修改等级颜色

代码语言:javascript
复制
ax1.scatter(x,y,c=data1,cmap='viridis',zorder=2)
ax2.scatter(x,y,c=data1,cmap='rainbow',zorder=2)

alpha

指定散点透明度

代码语言:javascript
复制
ax1.scatter(x,y,alpha=0.75,zorder=2)
ax2.scatter(x,y,alpha=0.25,zorder=2)

facecolor,edgecolor

强制指定颜色(不推荐)

代码语言:javascript
复制
ax1.scatter(x,y,facecolor='none',edgecolor='k',zorder=2)
ax2.scatter(x,y,facecolor='red',edgecolor='k',zorder=2)

linewidths

指定散点边界粗细

代码语言:javascript
复制
ax1.scatter(x,y,linewidths=1,facecolor='none',edgecolor='k',zorder=2)
ax2.scatter(x,y,linewidths=20,facecolor='none',edgecolor='k',zorder=2)

hatch

内部填充样式

代码语言:javascript
复制
ax1.scatter(x,y,s=100,hatch='xxxx',zorder=2)
ax2.scatter(x,y,s=100,hatch='**',zorder=2)

vmin,vmax

裁剪色条上下限

还有部分少见参数需要读者翻阅官方文档

四、散点图应用实例

A、最基础的传入数据,赋值给参数s,仅以散点大小表示数据变化

代码语言:javascript
复制
def sample_data():#编制实验数据
    x=range(1,21)#横坐标数据
    y=np.array([2,4,6,7,5,3,3,5,7,9,1115,10,8,4,7,8,3,2,5,7])#纵坐标数据
    data1=np.array([22,13,24,26,30,40,45,20,27,15,17,19,24,27,30,15,21,22,10,27])
    data2=np.array([32,19,27,29,30,44,120,39,67,45,17,19,24,87,30,15,61,22,26,37])
    data3=np.array([120,132,143,151,109,149,125,119,120,158,171,101,106,108,126,149,127,151,143,102])
    return x,y,data1,data2,data3
x,y,data1,data2,data3=sample_data()#获得实验数据

B、最基础的传入数据,赋值给c和cmap,仅以散点颜色表示大小

代码语言:javascript
复制
ax1.scatter(x,y,s=100,c=data2,cmap='Blues',zorder=2)
ax2.scatter(x,y,s=100,c=data3,cmap='Blues',zorder=2)

C、以散点大小和颜色同时表示一种数据的变化

代码语言:javascript
复制
ax1.scatter(x,y,s=data2,c=data2,cmap='Blues',zorder=2)
ax2.scatter(x,y,s=data3,c=data3,cmap='Reds',zorder=2)

这种方式是目前最为流行的散点数据显示方式,如果一个数据越大,那么他的填色越深并且散点面积越大,这样最能展示数据的大小变化情况。人眼捕获大小最为敏感,填色图能显示其等级程度,这种两结合是比较科学的数据分析方法。

D、以散点颜色展示一种数据,以散点大小展示另一种数据

代码语言:javascript
复制
ax1.scatter(x,y,s=data3,c=data2,cmap='Blues',edgecolor='k',zorder=2)
ax2.scatter(x,y,s=data1,c=data3,cmap='Reds',edgecolor='k',zorder=2)

这种数据显示方式是不推荐的,由于大小和颜色深浅不匹配,容易让读图者产生混淆。例如在蓝色子图中,颜色最深的散点其面积明显不是最大的,颜色和大小的不一致,容易使读图者产生误解。

五、带地图的散点图使用

A、最常用的方法——标记地理信息,如站点位置,站点海拔高度等

代码语言:javascript
复制
nameandstation={"恩施":[109.5,30.2],"利川":[109,30.3],"巴东":[110.34,31.04],"建始":[109.72,30.6],"宣恩":[109.49,29.987],"来凤":[109.407,29.493],"咸丰":[109.14,29.665],"鹤峰":[110.034,29.89]}
for key,value in nameandstation.items():
    ax.scatter(value[0] , value[1] , marker='.' , s=70 , color = "k" , zorder = 3)
    ax.text(value[0]-0.07 , value[1]+0.03 , key , fontsize = 6, color = "k")

站点海拔高度的标注参考链接:https://www.jianshu.com/p/2083fac7f2ce

原作者为简书大佬摸鱼咯。

B、进行显著性检验打点

气象家园上有相当多的高手讲解,我就不献丑了。比较火的参考链接:

http://bbs.06climate.com/forum.php?mod=viewthread&tid=92816&extra=page%3D1

原作者为气象家园大佬好久不见。

C、显示站点的大小和数值

可参考Python气象绘图教程(十四)

六、散点图的图例

散点图的图例添加,可供参考的有matplotlib官网实例,《Python数据科学手册》第四章p422,鄙号文章Python气象绘图教程(十四)

A、和折线图类似,默认的legend命令生成图例

ax.scatter(······,label='xxx')

ax.legend( )

B、使用legend_elements()命令获取当前scatter的图例句柄

代码语言:javascript
复制
N = 45
x, y = np.random.rand(2, N)
c = np.random.randint(1, 5, size=N)
s = np.random.randint(10, 220, size=N)

fig, ax = plt.subplots()

scatter = ax.scatter(x, y, c=c, s=s)

# produce a legend with the unique colors from the scatter
legend1 = ax.legend(*scatter.legend_elements(),
                    loc="lower left", title="Classes")
ax.add_artist(legend1)

# produce a legend with a cross section of sizes from the scatter
handles, labels = scatter.legend_elements(prop="sizes", alpha=0.6)
legend2 = ax.legend(handles, labels, loc="upper right", title="Sizes")

plt.show()
代码语言:javascript
复制
volume = np.random.rayleigh(27, size=40)
amount = np.random.poisson(10, size=40)
ranking = np.random.normal(size=40)
price = np.random.uniform(1, 10, size=40)

fig, ax = plt.subplots()

# Because the price is much too small when being provided as size for ``s``,
# we normalize it to some useful point sizes, s=0.3*(price*3)**2
scatter = ax.scatter(volume, amount, c=ranking, s=0.3*(price*3)**2,
                     vmin=-3, vmax=3, cmap="Spectral")

# Produce a legend for the ranking (colors). Even though there are 40 different
# rankings, we only want to show 5 of them in the legend.
legend1 = ax.legend(*scatter.legend_elements(num=5),
                    loc="upper left", title="Ranking")
ax.add_artist(legend1)

# Produce a legend for the price (sizes). Because we want to show the prices
# in dollars, we use the *func* argument to supply the inverse of the function
# used to calculate the sizes from above. The *fmt* ensures to show the price
# in dollars. Note how we target at 5 elements here, but obtain only 4 in the
# created legend due to the automatic round prices that are chosen for us.
kw = dict(prop="sizes", num=5, color=scatter.cmap(0.7), fmt="$ {x:.2f}",
          func=lambda s: np.sqrt(s/.3)/3)
legend2 = ax.legend(*scatter.legend_elements(**kw),
                    loc="lower right", title="Price")

plt.show()

C、使用Python气象绘图教程(十四)中的方法,绘制空数据散点图

ax.scatter( [ ] , [ ] , s=datamin)

ax.scatter( [ ] , [ ] , s=datamed)

ax.scatter( [ ] , [ ] , s=datamax)

参考资料:

简书,摸鱼咯:

https://www.jianshu.com/p/2083fac7f2ce

气象家园,好久不见:

http://bbs.06climate.com/forum.php?mod=viewthread&tid=92816&extra=page%3D1

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 气象学家 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档