应用python绘制全国温湿度表

开始之前简单交代一下背景,我研究生导师在全国做挂面干燥项目,不同地方的气候对挂面干燥工艺有一定影响,因此经常需要我帮忙统计国内某城市一年的温湿度变化情况。以前用excle表格ctrl+C、ctrl+V方式得到一个城市的某年温湿度表,这种方式重复性操作多,而且查找数据麻烦。在学习了python后,决定做一个一劳永逸的绘制温湿度的脚本。

本文分以下几个方面介绍:

  • 原始数据获取
  • 应用pandas对原始数据筛选、整理
  • 应用matplotlab绘制数据图像

一、原始数据获取

原始数据从中国气象数据中心地面资料下载获取,数据说明可在网站上找到相关文档。加载需自己需要的数据后,几个小时后可以从订单中下载数据。数据格式是.txt的文件,文件里面有每个月的下载地址(每个月都有单独一个下载地址)。在linux操作系统中,使用wget工具批量下载数据:

wget -i S201806271736073722600.txt -P tem

获得2019年全国主要城市的温湿度数据文件,文件名中含有RHU是相对湿度数据,含有TEM的是温度数据。每个文件名都标有年份和月份日期,如201902。

2019年温湿度数据.png

湿度数据一共有11列,其中第一列是城市编码,官网下载文件查询编码对应城市,其余每列数据代表查询如图湿度数据每列对应表。
湿度数据.png
湿度数据每列对应表.png

同理,温度数据一共是13列,每列数据含义也可查询

温度数据.png

温度数据每列对应表.png

到此原始数据已经获取完毕。

二、应用pandas对原始数据筛选、整理

1.遍历原始数据文件
应用golb工具,遍历文件夹内所有文件名,并将文件名存入list中:

 for month in range(1, 13):
     if month < 10:
         list_tem = glob.glob(raw_data_path + '/*TEM*20190' + str(month) + '*')
         list_rhu = glob.glob(raw_data_path + '/*RHU*20190' + str(month) + '*')
     else:
         list_tem = glob.glob(raw_data_path + '/*TEM*2019' + str(month) + '*')
         list_rhu = glob.glob(raw_data_path + '/*RHU*2019' + str(month) + '*')

用pandas按月读取数据,并将每月数据按行拼接,注意拼接时需要忽略行索引,设置ignore_index=True。此时读入的数据是一列

 tem_data = pd.DataFrame()
     for raw_file in list_tem:
         tem_data_month = pd.read_table(raw_file, header=None, dtype=str)
         tem_data = pd.concat([tem_data, tem_data_month], axis=0, ignore_index=True)

设置列索引标题,分别为城市ID、日期、最小温度、最大温度、平均温度。遍历数据框分别处理每一行数据,用split()方法按空格将数据拆分存入列表,再将每列对应的数据分别处理后填入对应列中。

tem_data.columns = ['city_id']
     tem_data['date'] = None
     tem_data['min'] = None
     tem_data['max'] = None
     tem_data['avg'] = None
     list_x = []
     for i in tqdm(range(len(tem_data))):
         list_x = tem_data['city_id'][i].split()  # 分开第i行,x列的数据。split()默认是以空格等符号来分割,返回一个列表
         tem_data['city_id'][i] = list_x[0]  # 分割形成的列表,并将数据填入对应列
         # tem_data['data'][i] = time.strptime(' - '.join([list_x[4], list_x[5] , list_x[6]]), "%Y - %m - %d")
         tem_data['data'][i] = '-'.join([list_x[4], list_x[5], list_x[6]])
         tem_data['min'][i] = float(list_x[9]) / 10
         tem_data['avg'][i] = float(list_x[7]) / 10
         tem_data['max'][i] = float(list_x[8]) / 10

用同样方法处理湿度数据。

rhu_data = pd.DataFrame()
for raw_file in list_rhu:
    rhu_data_month = pd.read_table(raw_file, header=None, dtype=str)
    rhu_data = pd.concat([rhu_data, rhu_data_month], axis=0, ignore_index=True) rhu_data.columns = ['city_id']
rhu_data['data'] = None
rhu_data['rhu'] = None
list_x = []
 for i in tqdm(range(len(rhu_data))):
     list_x = rhu_data['city_id'][i].split() 
     rhu_data['city_id'][i] = list_x[0]  
     rhu_data['data'][i] = '-'.join([list_x[4], list_x[5], list_x[6]])
     rhu_data['rhu'][i] = list_x[7]

将温度和湿度数据融合。

df = pd.merge(tem_data, rhu_data, how='left', on=['city_id', 'data'])
all_data = pd.concat([all_data, df], axis=0, ignore_index=True)

保存处理后的数据

all_data.to_csv(os.path.join(root_path, 'all_data.csv')

三、用matplotlab工具绘制温湿度图像

读取城市每天的数据,并去除数据中的未观测值,(32766为为观测值,将未观测值用前一有效数值替代)

 # city_id = 54618
    if city_id in df['city_id']:
        day_data = df[df['city_id'] == city_id]
    else:
        print("没有该编号对应的城市")
    # # print(df.shape)

    x = df["data"]
    month_min = []
    month_max = []
    month_avg = []
    month_rhu = []
    # print(day_data)
    min_tem = day_data['min'].values.tolist()
    max_tem = day_data['max'].values.tolist()
    avg_tem = day_data['avg'].values.tolist()
    rhu = day_data['rhu'].values.tolist()
    modify_invalid_value(3276.6, avg_tem)
    modify_invalid_value(3276.6, min_tem)
    modify_invalid_value(3276.6, max_tem)
    modify_invalid_value(32766, rhu)

计算月平均值,并将月平均值保存在数据框中

days = 0
    for day in [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]:
        month_min.append(sum(min_tem[days:days + day]) / day)
        month_max.append(sum(max_tem[days:days + day]) / day)
        month_avg.append(sum(avg_tem[days:days + day]) / day)
        month_rhu.append(sum(rhu[days:days + day]) / day)
        days = days + day
  manth_data = pd.DataFrame(
        {"city_id": city_id, "min_tem": month_min, "max_tem": month_max, "avg_tem": month_avg, "avg_rhu": month_rhu})

绘制数据,并保存图像和结果

 months = [month for month in range(1, 13)]
    fig, ax1 = plt.subplots()
    ax1.plot(months, month_min, label=u"min_Tem")
    ax1.plot(months, month_max, label=u"max_Tem")
    ax1.plot(months, month_avg, label=u"avg_Tem")
    ax2 = ax1.twinx()
    ax2.plot(months, month_rhu, '--', label=u"avg_Rhu")
    # _xtick_labels_ = [' '.join(time.asctime(time.strptime(i, "%Y-%m-%d")).split()[2:3])for i in df["data"]]
    ax1.set_xlabel(u"Month")
    ax1.set_ylabel(u"TEM(℃)")
    ax2.set_ylabel("RHU(%)")

    min_tem_val = min(month_min)
    max_rhu_val = max(month_rhu)
    ax1.set_ylim(min_tem_val - 5, 50)
    ax2.set_ylim(-100, max_rhu_val + 10)
    _xtick_labels = ["{}".format(i) for i in range(1, 13)]
    plt.xticks(months, _xtick_labels)
    # plt.title("温湿度表")
    for a, b in zip(months, month_min):
        ax1.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)
    for a, b in zip(months, month_max):
        ax1.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)
    for a, b in zip(months, month_avg):
        ax1.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)
    for a, b in zip(months, month_rhu):
        ax2.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)

    handles1, labels1 = ax1.get_legend_handles_labels()
    handles2, labels2 = ax2.get_legend_handles_labels()
    plt.legend(handles1 + handles2, labels1 + labels2, loc='lower center')
    plt.title('%d-TEM-RHU-Table' % city_id)
    plt.grid()
    plt.show()
    fig.savefig(os.path.join(root_path, 'image', str(city_id) + '_' + city_name + '.png'), bbox_inches='tight')

    # writer = pd.ExcelWriter(os.path.join(root_path,  'ShanDong.xlsx'))
    day_data.to_excel(writer, str(city_id) + city_name)
    manth_data.to_excel(writer, str(city_id) + city_name, startcol=9)

四、测试结果

用山东省六个城市的数据做测试。

city_id_dict = {54725: '惠民', 54776: '成山头', 54823: '济南', 54843: '潍坊', 54909: '定陶', 54916: '兖州'}
writer = pd.ExcelWriter(os.path.join(root_path, 'ShanDong.xlsx'))
for city_id, city_name in tqdm(city_id_dict.items()):
    main(city_id, city_name, writer)

writer.save()

输出结果:


54725_惠民.png

54776_成山头.png

54823_济南.png

54843_潍坊.png

54909_定陶.png

54916_兖州.png

各个城市温湿度数据输出到excle.png

五、总结

终于可以不用再复制粘贴的整理全国各地的温湿度数据了,而且将自己学的东西应用到日常工作中,提高工作效率是多么么么么么爽快的一件事啊。

仍未解决的问题:

1.生成的温湿度图,不能自动插入到相应excle对应的表格里。(不能再excle中追加插入图片)
2.没有解决生成图片中文出现编码错误。
3.数据处理不够简化,应该有很大的提升空间。

在代码过程中遇到的问题(找到相应解决方案):
数据读取与处理

1.如何遍历文件夹内文件?
2.怎样读取数据
3.怎样将不同文件的数据拼接
拼接时需要忽视行索引,
4.怎样将不同文件的数据融合
5.怎样设置dataframe的列标题
6.将读入的数据分为不同的列的方法
7.如何防止第一行数据当作列标题行
8.时间戳、时间元组、时间字符串的概念及相互转换
9.显示进度条的工具使用方法

图像绘制

1.如何设置横坐标
2.如何设置两个纵坐标
3.如何显示曲线中关键点数据值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348