python 散点图点的大小_气象绘图加强版(二)——散点图

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



一、简要谈谈散点图

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

f7b987833de667321a665b0d31c09f89.png

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

89e05454b1e7224e819df5b2eb4da620.png

图二    使用散点图表示站点突变信息 二、scatter( )绘图函数的基础运作 在前一章我们已经提到过,plot函数在某些时候可以简单理解为将scatter函数的散点连接起来,所以,其基础绘制方式也是依靠横轴、纵轴数据来确定散点在笛卡尔坐标系中的位置,并绘图。然后,依靠其关键字参数来进行修饰美化。 scatter( )函数的传入数据方式可参考plot( ),注意x、y数组长度必须一致。 三、scatter( )函数的常用关键字参数 scatter( )函数的核心部分当然是围绕着修饰散点进行,也匹配一定的其他修改命令。下面简要介绍常用scatter关键字命令。
scatter( )函数常用关键字参数

x

y

传入scatter( )的横纵轴数据,用于确定散点位置
s控制散点的大小
import numpy as npimport matplotlib.pyplot as pltplt.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,data2x,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=':')

713ce52b4c82b12f8786ec71f8b73459.png

c控制散点颜色
ax1.scatter(x,y,c='tab:green',zorder=2)ax2.scatter(x,y,c='tab:blue',zorder=2)

0672921d96009fd851f7d33c4d3e9077.png

marker指定散点样式
ax1.scatter(x,y,marker='*',zorder=2)ax2.scatter(x,y,marker='s',zorder=2)

cf11a59a3011c3672e63e5898d58c4ae.png

cmap与c参数配合,修改等级颜色
ax1.scatter(x,y,c=data1,cmap='viridis',zorder=2)ax2.scatter(x,y,c=data1,cmap='rainbow',zorder=2)

4886c5d6f04d820c2f37ad6c25d8c0e4.png

alpha指定散点透明度
ax1.scatter(x,y,alpha=0.75,zorder=2)ax2.scatter(x,y,alpha=0.25,zorder=2)

b72d181e01b4c0340b48c5a834a5ffb6.png

facecolor,edgecolor强制指定颜色(不推荐)
ax1.scatter(x,y,facecolor='none',edgecolor='k',zorder=2)ax2.scatter(x,y,facecolor='red',edgecolor='k',zorder=2)

bf623acc5721d2280d920b6d0a136991.png

linewidths指定散点边界粗细
ax1.scatter(x,y,linewidths=1,facecolor='none',edgecolor='k',zorder=2)ax2.scatter(x,y,linewidths=20,facecolor='none',edgecolor='k',zorder=2)

fa296f9fd5b8f8040fa59c2afddfbf9f.png

hatch内部填充样式
ax1.scatter(x,y,s=100,hatch='xxxx',zorder=2)ax2.scatter(x,y,s=100,hatch='**',zorder=2)

52832b25e9b3f173b62b23d087077f77.png

vmin,vmax裁剪色条上下限

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

四、散点图应用实例

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

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,data3x,y,data1,data2,data3=sample_data()#获得实验数据

ba5b8c9908a735d5e7ed59fb1ac31afa.png

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

ax1.scatter(x,y,s=100,c=data2,cmap='Blues',zorder=2)ax2.scatter(x,y,s=100,c=data3,cmap='Blues',zorder=2)

147fe328dcb6a7bbf14bdb854e6dbb30.png

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

ax1.scatter(x,y,s=data2,c=data2,cmap='Blues',zorder=2)ax2.scatter(x,y,s=data3,c=data3,cmap='Reds',zorder=2)

7db1bf204e084d398f30927d2b882c90.png

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

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

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)

4a99b99055de88a62199fa6694be23e3.png

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

五、带地图的散点图使用

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

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")

923493b0234dbba46d8c153913cea9b5.png

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

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

0af90cd1d741ae2e4813735a50a02143.png

B、进行显著性检验打点

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

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

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

935cda211d4cce0fa6a8f9d91599a029.png

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

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

六、散点图的图例

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

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

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

ax.legend( )

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

N = 45x, 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 scatterlegend1 = 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 scatterhandles, labels = scatter.legend_elements(prop="sizes", alpha=0.6)legend2 = ax.legend(handles, labels, loc="upper right", title="Sizes")plt.show()

7831f40c94819262129604a0d061015d.png

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)**2scatter = 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()

3d35835e830f058322fcebe9edb456a4.png

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

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

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

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

3f2e2bc217cc6483caea7226cf10a523.png

参考资料: 简书,摸鱼咯: https://www.jianshu.com/p/2083fac7f2ce 气象家园,好久不见: http://bbs.06climate.com/forum.php?mod=viewthread&tid=92816&extra=page%3D1 本公众号号: Python气象绘图教程(十四) matplotlib官网: https://matplotlib.org/gallery/lines_bars_and_markers/scatter_with_legend.html#sphx-glr-gallery-lines-bars-and-markers-scatter-with-legend-py

欢迎关注云台书使公众号

ced7c6000a9094c0d20d197787255086.png


版权声明:本文为weixin_32485965原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。