python | 降水数据分析(Ⅰ) 绘制全国降水四季分布图

写在前面

       上次交了作业(全国气温分布图)之后,老师开始让自己摸索处理数据的方法。为了这周先交一个成果上去(已经拖了两周了),决定画一个四季分布图和一个时序图,用两篇文章来记录。

下面的0.可以忽略


0.批量修改文件后缀(如txt文件 —>xlsx)(此步骤可忽略

此方法修改后的文件能用wps打开,但其他地方不一定能用

用记事本创建一个新的txt文件,写入ren *.txt *.xlsx(注意是英文空格)

 保存为.bat文件,保存在与需要修改后缀的文件同一目录下

保存后运行,即可看到后缀已修改

SOS: 修改后的excel表格无法用office打开,显示已损坏,目前没有解决方案......

用python读取修改后的表格也会报错  Excel file format cannot be determined, you must specify an engine manually.


下面开始正文 —— 画2002.3-2003.2的全国站点降水四季分布图

1.数据处理

  1-1 将三个月每天的站点数据合并到一个文本文件中

    用记事本创建一个新的txt文件,写入

    for %%i in (*.txt) do type %%i>>1.txt(注意是英文空格)(1.txt为合并后文件名称)

    即for %%i in (所有.这种格式的文件) do type %%i>>导出后的文件名称.文件格式

    与要合并的txt文件保存在同级目录下,运行就可以了

  1-2  用excel读取、计算每个站点三个月降水的平均值(excel处理方法见上一篇文章)

2.绘制春夏秋冬分布图 直接上代码

from pickletools import long4
from pkgutil import extend_path
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import pandas as pd
from cartopy.io import shapereader as shpreader

df1 = pd.read_excel(r"D:\春 终版.xlsx")
df2 = pd.read_excel(r"D:\夏 终.xlsx")
df3 = pd.read_excel(r"D:\秋 终.xlsx")
df4 = pd.read_excel(r"D:\冬 终.xlsx")


lat1 = df1['Lat']
lon1 = df1['Lon']
pre1 = df1['平均值项:PRE_Time_2020']

lat2 = df2['Lat']
lon2 = df2['Lon']
pre2 = df2['平均值项:PRE_Time_2020']

lat3 = df3['Lat']
lon3 = df3['Lon']
pre3 = df3['平均值项:PRE_Time_2020']

lat4 = df4['Lat']
lon4 = df4['Lon']
pre4 = df4['平均值项:PRE_Time_2020']


# 建立画布
fig2 = plt.figure(figsize=(20, 12))
norm = matplotlib.colors.Normalize(vmin=0, vmax=40)
proj = ccrs.PlateCarree(central_longitude=105)


leftlon, rightlon, lowerlat, upperlat = (70, 140, 15, 55)  # 根据上下限确定范围,至少为10°


# 春 ------------------------------------------------------------------------------------
#左 底 宽 高
f2_ax1 = fig2.add_axes([0.2, 0.35, 0.45, 0.225], projection=proj)
# 在画布的绝对坐标建立子图
f2_ax1.set_extent([leftlon, rightlon, lowerlat, upperlat],
                  crs=ccrs.PlateCarree())
# 海岸线,50m精度
f2_ax1.add_feature(cfeature.COASTLINE.with_scale('50m'))
# 湖泊数据(但是这个貌似只画了比较大的湖泊,比如贝湖巴湖)
f2_ax1.add_feature(cfeature.LAKES, alpha=0.5)
# 以下6条语句是定义地理坐标标签格式
f2_ax1.set_xticks(np.arange(leftlon, rightlon+10, 10),
                  crs=ccrs.PlateCarree())

f2_ax1.set_yticks(np.arange(lowerlat, upperlat+10, 10),
                  crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter()
lat_formatter = LatitudeFormatter()
f2_ax1.xaxis.set_major_formatter(lon_formatter)
f2_ax1.yaxis.set_major_formatter(lat_formatter)
f2_ax1.set_title('Spr', loc='left', fontsize=10)
# 读取shp文件
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
# 绘制中国国界省界九段线等等
f2_ax1.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)
# 添加南海,实际上就是新建一个子图覆盖在之前子图的右下角
f2_ax2 = fig2.add_axes([0.505, 0.353, 0.04, 0.07], projection=proj)
f2_ax2.set_extent([105, 125, 0, 25], crs=ccrs.PlateCarree())
f2_ax2.add_feature(cfeature.COASTLINE.with_scale('50m'))
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
f2_ax2.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)

f1 = f2_ax1.scatter(lon1, lat1, s=2, c=pre1, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)
f2 = f2_ax2.scatter(lon1, lat1, s=2, c=pre1, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)

# 夏-------------------------------------------------------------------------------------
f2_ax3 = fig2.add_axes([0.5, 0.35, 0.45, 0.225], projection=proj)
# 在画布的绝对坐标建立子图
f2_ax3.set_extent([leftlon, rightlon, lowerlat, upperlat],
                  crs=ccrs.PlateCarree())
# 海岸线,50m精度
f2_ax3.add_feature(cfeature.COASTLINE.with_scale('50m'))
# 湖泊数据(但是这个貌似只画了比较大的湖泊,比如贝湖巴湖)
f2_ax3.add_feature(cfeature.LAKES, alpha=0.5)
# 以下6条语句是定义地理坐标标签格式
f2_ax3.set_xticks(np.arange(leftlon, rightlon+10, 10),
                  crs=ccrs.PlateCarree())

f2_ax3.set_yticks(np.arange(lowerlat, upperlat+10, 10),
                  crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter()
lat_formatter = LatitudeFormatter()
f2_ax3.xaxis.set_major_formatter(lon_formatter)
f2_ax3.yaxis.set_major_formatter(lat_formatter)
f2_ax3.set_title('Sum', loc='left', fontsize=10)
# 读取shp文件
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
# 绘制中国国界省界九段线等等
f2_ax3.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)
# 添加南海,实际上就是新建一个子图覆盖在之前子图的右下角
f2_ax4 = fig2.add_axes([0.805, 0.353, 0.04, 0.07], projection=proj)
f2_ax4.set_extent([105, 125, 0, 25], crs=ccrs.PlateCarree())
f2_ax4.add_feature(cfeature.COASTLINE.with_scale('50m'))
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
f2_ax4.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)

f3 = f2_ax3.scatter(lon2, lat2, s=2, c=pre2, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)
f4 = f2_ax4.scatter(lon2, lat2, s=2, c=pre2, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)
# 秋-------------------------------------------------------------------------------------
f2_ax5 = fig2.add_axes([0.2, 0.05, 0.45, 0.225], projection=proj)
# 在画布的绝对坐标建立子图
f2_ax5.set_extent([leftlon, rightlon, lowerlat, upperlat],
                  crs=ccrs.PlateCarree())
# 海岸线,50m精度
f2_ax5.add_feature(cfeature.COASTLINE.with_scale('50m'))
# 湖泊数据(但是这个貌似只画了比较大的湖泊,比如贝湖巴湖)
f2_ax5.add_feature(cfeature.LAKES, alpha=0.5)
# 以下6条语句是定义地理坐标标签格式
f2_ax5.set_xticks(np.arange(leftlon, rightlon+10, 10),
                  crs=ccrs.PlateCarree())

f2_ax5.set_yticks(np.arange(lowerlat, upperlat+10, 10),
                  crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter()
lat_formatter = LatitudeFormatter()
f2_ax5.xaxis.set_major_formatter(lon_formatter)
f2_ax5.yaxis.set_major_formatter(lat_formatter)
f2_ax5.set_title('Fal', loc='left', fontsize=10)
# 读取shp文件
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
# 绘制中国国界省界九段线等等
f2_ax5.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)
# 添加南海,实际上就是新建一个子图覆盖在之前子图的右下角
f2_ax6 = fig2.add_axes([0.505, 0.053, 0.04, 0.07], projection=proj)
f2_ax6.set_extent([105, 125, 0, 25], crs=ccrs.PlateCarree())
f2_ax6.add_feature(cfeature.COASTLINE.with_scale('50m'))
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
f2_ax6.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)

f5 = f2_ax5.scatter(lon3, lat3, s=2, c=pre3, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)
f6 = f2_ax6.scatter(lon3, lat3, s=2, c=pre3, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)
# 冬-------------------------------------------------------------------------------------
f2_ax7 = fig2.add_axes([0.5, 0.05, 0.45, 0.225], projection=proj)
# 在画布的绝对坐标建立子图
f2_ax7.set_extent([leftlon, rightlon, lowerlat, upperlat],
                  crs=ccrs.PlateCarree())
# 海岸线,50m精度
f2_ax7.add_feature(cfeature.COASTLINE.with_scale('50m'))
# 湖泊数据(但是这个貌似只画了比较大的湖泊,比如贝湖巴湖)
f2_ax7.add_feature(cfeature.LAKES, alpha=0.5)
# 以下6条语句是定义地理坐标标签格式
f2_ax7.set_xticks(np.arange(leftlon, rightlon+10, 10),
                  crs=ccrs.PlateCarree())

f2_ax7.set_yticks(np.arange(lowerlat, upperlat+10, 10),
                  crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter()
lat_formatter = LatitudeFormatter()
f2_ax7.xaxis.set_major_formatter(lon_formatter)
f2_ax7.yaxis.set_major_formatter(lat_formatter)
f2_ax7.set_title('Win', loc='left', fontsize=10)
# 读取shp文件
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
# 绘制中国国界省界九段线等等
f2_ax7.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)
# 添加南海,实际上就是新建一个子图覆盖在之前子图的右下角
f2_ax8 = fig2.add_axes([0.805, 0.053, 0.04, 0.07], projection=proj)
f2_ax8.set_extent([105, 125, 0, 25], crs=ccrs.PlateCarree())
f2_ax8.add_feature(cfeature.COASTLINE.with_scale('50m'))
china = shpreader.Reader(r"D:\bou2_4l.dbf").geometries()
f2_ax8.add_geometries(china, ccrs.PlateCarree(),
                      facecolor='none', edgecolor='black', zorder=1)

f7 = f2_ax7.scatter(lon4, lat4, s=2, c=pre4, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)
f8 = f2_ax8.scatter(lon4, lat4, s=2, c=pre4, cmap='seismic',
                    transform=ccrs.PlateCarree(), vmin=0, vmax=16)


# colorbar 左 下 宽 高
l = 0.88
b = 0.06
w = 0.015
h = 0.5

# 对应 l,b,w,h;设置colorbar位置;
rect = [l, b, w, h]


cbar_ax = fig2.add_axes(rect)
cb = plt.colorbar(f4, cax=cbar_ax, extend='both')

plt.savefig(r'D:\桌面\Seasonal Precipitation.png', dpi=300)
plt.show()

绘制结果

 

3.一些参考和解释

1.为了方便,直接用了第一次画图的代码,然后因为太懒了,就没有用循环来写代码。(实际上是学艺不精)

2.与第一次画图的区别

   为了给四幅图设置相同的colorbar,我在网上找了好多,但是都不是用plt.figure.add_axes方法画的图,就不适用于我这个图,只好在scatter中设置上下限。

   关于为什么不用subplots等快捷的方法画这四幅图:因为图中还有南海子图,我没想明白怎么画子图套小图。。。

   新增:对于colorbar添加了上下限(在scatter函数中,vmin和vmax)和尖角(在plt.colorbar中,extend=‘both’)

3.下面是在画图过程中搜索到觉得值得收藏的几篇文章

(13条消息) matplotlib contourf colorbar放到下方_Python空间绘图Colorbar详解_weixin_39790102的博客-CSDN博客

(14条消息) [Python3] Matplotlib —— (九) 多子图_TreasureAI的博客-CSDN博客

最全Python绘制多子图总结 - 知乎 (zhihu.com)

(14条消息) Matplotlib学习手册A005_Figure的add_axes()方法_Python草堂的博客-CSDN博客_add_axes

scatter函数参数(14条消息) Python中scatter函数参数详解_幸运六叶草的博客-CSDN博客_python scatter参数详解

4.不得不感慨官网yyds matplotlib.axes.Axes.scatter — Matplotlib 3.5.2 documentation

5.希望时序图顺利(合十)

  • 36
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值