使用数据集进行可视化

发布于 2022-04-06  464 次阅读


使用Python模块csv来处理CSV格式存储的天气数据,找出两个地区在一段时间呢的最高温度和最低温度。然后,使用Matplotlib根据下载的数据创建一个图表,展示两个不同地区的温度变换:阿拉斯加州锡特卡和季利夫尼牙死亡谷。然后,使用模块json访问JSON格式存储的地震数据,并使用Plotly绘制一幅散点图,展示这些地震的位置和震级。

CSV文件格式

要在文本文件中存储数据,一个简单方式是将数据作为一系列以逗号分隔的值写入文件。这样的文件称为CSV文件。例如:

"USW00025333","SITKA AIRPORT","AK US","2018-01-01","0.45",,"48","38"

分析CSV文件头

csv模块包含在Python标准库中,可用于分析CSV文件中的数据行。
先查看这个文件的第一行,其中的一系列文件头指出了后续各行包含的是什么样的信息。

import csv

filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    print(header_row)

file
导入csv。调用csv.reader()并将f对象作为实参赋值给它。从而创建一个与该文件相关联的阅读器对象。这个阅读器对象被赋给了reader。
模块csv包含函数next(),调入它并传入阅读器对象时,将返回文件中的下一行。只调用next()一次,因此得到的是文件第一行数据,其包含文件头。
reader处理文件中以逗号分隔的第一行数据,并将每项数据都作为一个元素存储在列表中。文件头STAION表示数据的气象站的编码。这个文件头的位置表明,每行的第一个值都是气象站编码。NAME气象站名称。DATA日期。TMAX最高气温,TMIN最低气温。

打印文件头及其位置

import csv

filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    for index,column_header in enumerate(header_row):
        print(index,column_header)

file
在循环中,对列表调用了enumerate()来获取每个元素的索引及其值。

提取并读取数据

import csv

filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    highs = []
    for row in reader:
        high = int(row[5])
        highs.append(high)

print(highs)

file

绘制温度图标

为可视化这些温度数据。首先使用Matplotlib创建一个显示每日最高温度的简单图形。

import csv

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    highs = []
    for row in reader:
        high = int(row[5])
        highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(highs,c='red')

# 设置图形的格式
ax.set_title("2018年7月每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file

模块datetime

读取时间列时,获得的是一个字符串,因此需要将字符串"2018-7-1"转换为一个表示相应日期的对象。为创建一个表示2018年7月1日的对象。可以使用模块datetime中的方法strptime()。

from datetime import datetime
first_data = datetime.strptime('2018-07-01','%Y-%m-%d')
print(first_data)
2018-07-01 00:00:00

首先导入模块datetime中的datetime类,再调用方法strptime(),并将包含所需日期的字符串作为第一个实参。第二个实参告诉Python如何设置日期的格式。在这里,‘%Y-’让Python将字符串中的第一个连字符前面的部分视为四位的年份,'%m-'将第二个连字符前面的部分表示为月份,'%d'让最后一部分视为月份中的一天(1-31)。
方法strptime()可接受各种实参,并根据它们来决定如何解读日期。

实参 含义
%A 星期几,如Monday
%B 月份名,如January
%m 用数表示的月份(01~12)
%d 用数表示的月份中的每一天(01~31)
%Y 四位的年份,如2022
%y 两位的年份,如22
%H 24小时制度的小时数(00~23)
%I 12小时制的小时数(01~12)
%p am或pm
%M 分钟数(00~59)
%S 秒数(00~61)

在图标中添加日期

可以通过提取日期和最高温度绘图:

import csv
from datetime import datetime

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # 从文件中获取日期和最高温度
    dates,highs = [],[]
    for row in reader:
        current_date = datetime.strptime(row[2],'%Y-%m-%d')
        high = int(row[5])
        dates.append(current_date)
        highs.append(high)
    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    # highs = []
    # for row in reader:
    #     high = int(row[5])
    #     highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red')

# 设置图形的格式
ax.set_title("2018年7月每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file
调用fig.autofmt_xdate()来绘制倾斜的日期标签,以免彼此重叠。

涵盖更长的时间

import csv
from datetime import datetime

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/sitka_weather_2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # 从文件中获取日期和最高温度
    dates,highs = [],[]
    for row in reader:
        current_date = datetime.strptime(row[2],'%Y-%m-%d')
        high = int(row[5])
        dates.append(current_date)
        highs.append(high)
    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    # highs = []
    # for row in reader:
    #     high = int(row[5])
    #     highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red')

# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file

再绘制一个数据系列

添加最低温气温。

import csv
from datetime import datetime

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/sitka_weather_2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # 从文件中获取日期和最高温度和最低温气温。
    dates,highs,lows = [],[],[]
    for row in reader:
        current_date = datetime.strptime(row[2],'%Y-%m-%d')
        high = int(row[5])
        low = int(row[6])
        dates.append(current_date)
        highs.append(high)
        lows.append(low)
    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    # highs = []
    # for row in reader:
    #     high = int(row[5])
    #     highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red')
ax.plot(dates,lows,c='blue')

# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file

给图标区域着色

通过着色来呈现每天的温度范围。为此,将使用方法fill_betweem()它将接受一个x值系列和两个y值系列并填充两个y值系列之间的空间。

import csv
from datetime import datetime

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/sitka_weather_2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # 从文件中获取日期和最高温度和最低温气温。
    dates,highs,lows = [],[],[]
    for row in reader:
        current_date = datetime.strptime(row[2],'%Y-%m-%d')
        high = int(row[5])
        low = int(row[6])
        dates.append(current_date)
        highs.append(high)
        lows.append(low)
    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    # highs = []
    # for row in reader:
    #     high = int(row[5])
    #     highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red',alpha=0.5)
ax.plot(dates,lows,c='blue',alpha=0.5)
ax.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1)

# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file
alpha指定颜色的透明度。0为完全透明,1表示完全不透明。
fill_between()传递一个x值系列以及两个y值系列。实参facecolor指定填充区域的颜色。

错误检查

偶尔气象站某天数据确实。如果未处理,缺失数据可能引发异常。如果不妥善处理,可能导致程序奔溃。
例如:

import csv

filename = './data/death_valley_2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    for index,column_header in enumerate(header_row):
        print(index,column_header)

file
最高温和最低温索引与之前不同。
另外,这个气象站没有记录平均温度。而记录了TOBS,即特定时间点的温度。
为了演示缺失数据时出现的状况:

import csv
from datetime import datetime

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/death_valley_2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # 从文件中获取日期和最高温度和最低温气温。
    dates,highs,lows = [],[],[]
    for row in reader:
        current_date = datetime.strptime(row[2],'%Y-%m-%d')
        high = int(row[4])
        low = int(row[5])
        dates.append(current_date)
        highs.append(high)
        lows.append(low)
    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    # highs = []
    # for row in reader:
    #     high = int(row[5])
    #     highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red',alpha=0.5)
ax.plot(dates,lows,c='blue',alpha=0.5)
ax.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1)

# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file
直接对缺失数据的情形做处理。
为此,在从CSV文件中读取值时执行错误检查代码,对可能出现的异常进行处理。如下:

import csv
from datetime import datetime

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C://Windows/Fonts/STKAITI.TTF", size=15)

filename = './data/death_valley_2018_simple.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    # 从文件中获取日期和最高温度和最低温气温。
    dates,highs,lows = [],[],[]
    for row in reader:
        current_date = datetime.strptime(row[2],'%Y-%m-%d')
        try:
            high = int(row[4])
            low = int(row[5])
        except ValueError:
            print(f"Missing data for {current_date}")
        else:
            dates.append(current_date)
            highs.append(high)
            lows.append(low)
    # for index,column_header in enumerate(header_row):
    #     print(index,column_header)
    # 从文件中获取最高温度
    # highs = []
    # for row in reader:
    #     high = int(row[5])
    #     highs.append(high)

# 根据最高温度绘制图形
plt.style.use('seaborn')
fig,ax = plt.subplots()
ax.plot(dates,highs,c='red',alpha=0.5)
ax.plot(dates,lows,c='blue',alpha=0.5)
ax.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1)

# 设置图形的格式
ax.set_title("2018年每日最高温度",fontsize=24,fontproperties=font)
ax.set_xlabel('',fontsize=16,fontproperties=font)
fig.autofmt_xdate()
ax.set_ylabel('温度(F)',fontsize=16,fontproperties=font)
ax.tick_params(axis='both',which='major',labelsize=16)

plt.show()

file
使用的很多数据集都可能缺失数据、格式不正确或数据本身不正确,对于这样子的情形,可以使用try-expect-else处理。
在有些情况下,需要使用continue来跳过一些数据,或者使用remove()或del将以提取的数据删除,只要能进行精确而有意义的可视化,采取任何关用的方法都是可以的。


擦肩而过的概率