接着上節繼續學習,在本章中,你將從網上下載數據,並對這些數據進行可視化。網上的數據多得難以置信,且大多未經過仔細檢查。如果能夠對這些數據進行分析,你就能發現別人沒有發現的規律和關聯。我們將訪問並可視化以兩種常見格式存儲的數據:CSV和JSON。我們將使用Python模塊csv來處理以CSV(逗號分隔的值)格式存儲的天氣數據,找出兩個不同地區在一段時間內的最高溫度和最低溫度。然后,我們將使用matplotlib根據下載的數據創建一個圖表,展示兩個不同地區的氣溫變化:阿拉斯加錫特卡和加利福尼亞死亡谷。在本章的后面,我們將使用模塊json來訪問以JSON格式存儲的人口數據,並使用Pygal繪制一幅按國別划分的人口地圖。
一 CSV格式
要在文本文件中存儲數據,最簡單的方式是將數據作為一系列以逗號分隔的值(CSV)寫入文件。這樣的文件稱為CSV文件。例如,下面是一行CSV格式的天氣數據:
2014-1-5,61,44,26,18,7,-1,56,30,9,30.34,30.27,30.15,,,,10,4,,0.00,0,,195
二 分析CSV文件頭
csv模塊包含在Python標准庫中,可用於分析CSV文件中的數據行,讓我們能夠快速提取感興趣的值。下面先來查看這個文件的第一行,其中包含一系列有關數據的描述:
import csv
filename = 'sitka_weather_07-2014.csv'
with open(filename) as f :
reader = csv.reader(f)
header_row = next(reader)
print(header_row)
(1)調用csv.reader(),並將前面存儲的文件對象作為實參傳遞給它,從而創建一個與該文件相關聯的閱讀器(reader)對象。我們將這個閱讀器對象存儲在reader中。
(2)模塊csv包含函數next(),調用它並將閱讀器對象傳遞給它時,它將返回文件中的下一行。在前面的代碼中,我們只調用了next()一次,因此得到的是文件的第一行,
結果如下:['AKDT', 'Max TemperatureF', 'Mean TemperatureF', 'Min TemperatureF', 'Max Dew PointF', 'MeanDew PointF', 'Min DewpointF', 'Max Humidity', ' Mean Humidity', ' Min Humidity', ' Max Sea Level PressureIn', ' Mean Sea Level PressureIn', ' Min Sea Level PressureIn', ' Max VisibilityMiles', ' Mean VisibilityMiles', ' Min VisibilityMiles', ' Max Wind SpeedMPH', ' Mean Wind SpeedMPH', ' Max Gust SpeedMPH', 'PrecipitationIn', ' CloudCover', ' Events', ' WindDirDegrees']
這個csv文件時這樣的。

三 打印頭文件以及其位置
為讓文件頭數據更容易理解,將列表中的每個文件頭及其位置打印出來:
import csv
filename = 'sitka_weather_07-2014.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)
結果如下:

四 提取並讀取數據
知道需要哪些列中的數據后,我們來讀取一些數據。首先讀取每天的最高氣溫:
import csv
filename = 'sitka_weather_07-2014.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[1])
highs.append(high)
print(highs)
結果如下圖:
[64, 71, 64, 59, 69, 62, 61, 55, 57, 61, 57, 59, 57, 61, 64, 61, 59, 63, 60, 57, 69, 63, 62, 59, 57, 57, 61, 59, 61, 61, 66]
五 繪制氣溫圖標
import csv from matplotlib import pyplot as plt filename = 'sitka_weather_07-2014.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[1]) highs.append(high) print(highs) fig = plt.figure(dpi=128,figsize=(10,6)) plt.plot(highs,c="red") #設置圖形的格式 plt.title("Daily high temperatures,July 2014,", fontsize=24) plt.xlabel("",fontsize=16) plt.ylabel("Temperature(F)",fontsize=16) plt.tick_params(axis="both",which ="major",labelsize=16) plt.show()
結果如下圖:

六 模塊datetime
首先導入了模塊datetime中的datetime類,然后調用方法strptime(),並將包含所需日期的字符串作為第一個實參。第二個實參告訴Python如何設置日期的格式。在這個示例中,'%Y-'讓Python將字符串中第一個連字符前面的部分視為四位的年份;'%m-'讓Python將第二個連字符前面的部分視為表示月份的數字;而'%d'讓Python將字符串的最后一部分視為月份中的一天(1~31)。
方法strptime()可接受各種實參,並根據它們來決定如何解讀日期。一下列出了其中一些這樣的實參:

七 在圖表中添加日期
知道如何處理CSV文件中的日期后,就可對氣溫圖形進行改進了,即提取日期和最高氣溫,並將它們傳遞給plot(),如下所示:
import csv from matplotlib import pyplot as plt from datetime import datetime filename = 'sitka_weather_07-2014.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) #從文件中獲取日期和最高氣溫 dates,highs=[],[] for row in reader : current_date = datetime.strptime(row[0],"%m/%d/%Y") dates.append(current_date) high = int(row[1]) highs.append(high) print(highs) fig = plt.figure(dpi=128,figsize=(10,6)) plt.plot(dates,highs,c="red") #設置圖形的格式 plt.title("Daily high temperatures,July 2014,", fontsize=24) plt.xlabel("",fontsize=16) fig.autofmt_xdate() plt.ylabel("Temperature(F)",fontsize=16) plt.tick_params(axis="both",which ="major",labelsize=16) plt.show()
我們創建了兩個空列表,用於存儲從文件中提取的日期和最高氣溫(見)。然后,我們將包含日期信息的數據(row[0])轉換為datetime對象,並將其附加到列表dates末尾。我們將日期和最高氣溫值傳遞給plot()。我們調用了fig.autofmt_xdate()來繪制斜的日期標簽,以免它們彼此重疊。下圖顯示了改進后的圖表。
八 再繪制一個數據系列
改進后的圖表顯示了大量意義深遠的數據,但我們可以在其中再添加最低氣溫數據,使其更有用。為此需要從數據文件中提取最低氣溫,並將它們添加到圖表中,如下所示:
import csv
from matplotlib import pyplot as plt
from datetime import datetime
filename = 'sitka_weather_2014.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)
#從文件中獲取日期和最高氣溫,最低氣溫
dates,highs,lows=[],[],[]
for row in reader :
current_date = datetime.strptime(row[0],"%Y-%m-%d")
dates.append(current_date)
low=int(row[3])
lows.append(low)
high = int(row[1])
highs.append(high)
# print(highs)
fig = plt.figure(dpi=128,figsize=(10,6))
plt.plot(dates,highs,c="red")
plt.plot(dates,lows,c="blue")
#設置圖形的格式
plt.title("Daily high temperatures - 2014,", fontsize=24)
plt.xlabel("",fontsize=16)
fig.autofmt_xdate()
plt.ylabel("Temperature(F)",fontsize=16)
plt.tick_params(axis="both",which ="major",labelsize=16)
plt.show()
效果圖如下:

九 給圖標區域着色
添加兩個數據系列后,我們就可以了解每天的氣溫范圍了。下面來給這個圖表做最后的修飾,通過着色來呈現每天的氣溫范圍。為此,我們將使用方法fill_between(),它接受一個x值系列和兩個y值系列,並填充兩個y值系列之間的空間:
plt.plot(dates,highs,c="red",alpha=0.5) plt.plot(dates,lows,c="blue",alpha=0.5) plt.fill_between(dates,highs,lows,facecolor="blue",alpha=0.1)
(1)實參alpha指定顏色的透明度。Alpha值為0表示完全透明,1(默認設置)表示完全不透明。通過將alpha設置為0.5,可讓紅色和藍色折線的顏色看起來更淺。
(2)我們向fill_between()傳遞了一個x值系列:列表dates,還傳遞了兩個y值系列:highs和lows。
(3)實參facecolor指定了填充區域的顏色,我們還將alpha設置成了較小的值0.1,讓填充區域將兩個數據系列連接起來的同時不分散觀察者的注意力。
(4)顯示了最高氣溫和最低氣溫之間的區域被填充的圖表如下:

未完待續!元旦三天小長假已經來了,祝大家元旦快樂!
