經過上一篇談談Python實戰數據可視化之matplotlib模塊(基礎篇)的學習,咱們初步瞭解了matplotlib模塊的pyplot基礎,本節實戰將利用CSV模塊獲取某地的天氣數據,而且使用matplotlib模塊將天氣數據可視化。python
鑑於Python編程從入門到實戰這本書的配套資源網上難找的悲傷,我深有體會。因此,在此提供連接供下載(有幫助點個贊支持下我哦(●'◡'●)):
百度雲連接:https://pan.baidu.com/s/1-XE0pBS8IaDLoUBdO8hDOw 密碼:n39g編程
CSV - 逗號分隔值文件格式,逗號分隔值(Comma-Separated Values,CSV,有時也稱爲字符分隔值,由於分隔字符也能夠不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。純文本意味着該文件是一個字符序列,不含必須像二進制數字那樣被解讀的數據。CSV文件由任意數目的記錄組成,記錄間以某種換行符分隔;每條記錄由字段組成,字段間的分隔符是其它字符或字符串,最多見的是逗號或製表符。一般,全部記錄都有徹底相同的字段序列。一般都是純文本文件。
例如:app
Country,Indicator,Year,Value AFG,NGDP_R,2002,183.26 AFG,NGDP_R,2003,198.736 AFG,NGDP_R,2004,200.069 AFG,NGDP_R,2005,223.737 AFG,NGDP_R,2006,235.731 AFG,NGDP_R,2007,267.177 AFG,NGDP_R,2008,277.498 AFG,NGDP_R,2009,334.621 AFG,NGDP_R,2010,362.857 AFG,NGDP_R,2011,386.368 AFG,NGDP_R,2012,440.336 AFG,NGDP_R,2013,456.453 ....................... .......................
先將sitka_weather_07-2014.csv文件放到項目同一目錄下,而後利用Python標準庫提供的CSV模塊能夠用於分析CSV文件中的數據行(也就是上面提到的記錄),讓咱們能快速提取感興趣的值。案例代碼以下:ide
import csv # 包含一個sitka城市七月份天氣信息的CSV文件,裏面都是用逗號隔開 filename = 'sitka_weather_07-2014.csv' # 打開csv文件,實例化一個csv模塊的reader閱讀器對象,是一個可迭代對象,因此可使用for循環遍歷該reader閱讀器對象, # 也能夠調用BIF-next函數遍歷下一行,須要注意的是reader裏面的每行記錄只能被遍歷一次,其中reader有一個line_num屬性返回遍歷過程當中對應的行號。 with open(filename) as f: reader = csv.reader(f) # 返回的是一個csv的閱讀器對象,直接打印獲取不到裏面的內容 print(reader) # 打印出的是<_csv.reader object at 0x000002D1B24912B8> head_row = next(reader) # 返回第一行的記錄內容組成的字符串列表 print(head_row) # 打印 ['AKDT', 'Max TemperatureF'...] for row in reader: # 根據閱讀器對象的記錄(一行算一個記錄)只能遍歷一次的特性,行號從2開始了哦 print(reader.line_num, row) # 打印 2 ['2014-7-1', '64', '56', '50'....]
運行結果以下:
好了,初步獲取到了CSV文件的內容,可是咱們有一點要注意,就是reader裏面的每行記錄只能被遍歷一次,咱們下面添加一行代碼更深入領會:函數
import csv filename = 'sitka_weather_07-2014.csv' with open(filename) as f: reader = csv.reader(f) print(reader) print(list(reader)) # 值得注意的是,當先調用 print(list(reader)),發現遍歷到最後了,再執行後面的代碼就報錯了 head_row = next(reader) print(head_row) for row in reader: print(reader.line_num, row)
運行結果以下:
對上面的結果進行分析:對於list內置函數,內部實現大概能夠猜到是先將reader對象裏面的記錄遍歷再添加進一個列表中,而後返回整個列表。調用list內置函數其實已經遍歷一次了,遍歷指針指向了最後一個記錄,而且由於reader的記錄(一行算一個記錄)只能被遍歷一次的特性,因此後面的代碼再遍歷reader對象就沒啥意義了。學習
咱們前面已經知道怎麼獲取天氣數據了,那麼咱們將使用pyplot模塊繪製阿拉斯加錫特卡2014年7月每日最高氣溫折線圖。代碼以下(註釋有助於理解代碼):3d
# 繪製錫特卡7月份的天氣數據 # 導入python支持的csv模塊,用來處理csv文件,分析csv文件中的數據行,讓咱們提取咱們感興趣的值 import csv # 導入matplotlib包裏的pyplot模塊,用於可視化獲取到的天天最高溫度 from matplotlib import pyplot as plt from datetime import datetime # 包含一個城市天氣信息的CSV文件,裏面都是用逗號隔開 filename = 'sitka_weather_07-2014.csv' # 打開csv文件,實例化一個csv模塊的reader閱讀器對象 with open(filename) as f: reader = csv.reader(f) head_row = next(reader) # 返回第一行的記錄內容組成的字符串列表,例如:['1','2'....] highs = [] # 用於存儲天天最高的溫度 dates = [] # 用於存儲日期 for row in reader: # row也是返回遍歷行的記錄內容組成的字符串列表 current_date = datetime.strptime(row[0], "%Y-%m-%d") # 講時間字符串轉化爲指定格式的datetime對象 dates.append(current_date) high = int(row[1]) # 因爲前面已經next過一次了,根據reader只能被遍歷一次的性質,這裏for循環就從第二行開始遍歷 highs.append(high) # 將天天的最高溫度保存在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=14) plt.show()
運行結果以下:
仔細觀察上面的運行結果,X軸仍是與書本圖片有些出入,其實無礙,這是正確的,由於咱們運行的結果也是7月初開始,只不過X軸把6月份也包括進去了。指針
前面咱們繪製了阿拉斯加錫特卡7月份每日最高氣溫折線圖,如今咱們將獲取阿拉斯加錫特卡2014年整一年的天氣數據,再繪製阿拉斯加錫特卡2014年每日最高氣溫和最低氣溫折線圖。咱們先將sitka_weather_2014.csv文件也放到項目同一目錄下。代碼以下:code
# 繪製錫特卡全年的天氣數據,未進行錯誤檢查 # 導入python支持的csv模塊,用來處理csv文件,分析csv文件中的數據行,讓咱們提取咱們感興趣的值 import csv # 導入matplotlib包裏的pyplot模塊,用於可視化獲取到的天天最高溫度 from matplotlib import pyplot as plt from datetime import datetime # 包含一個城市天氣信息的CSV文件,裏面都是用逗號隔開 filename = 'sitka_weather_2014.csv' # 打開csv文件,實例化一個csv模塊的reader閱讀器對象 with open(filename) as f: reader = csv.reader(f) head_row = next(reader) # 返回第一行的記錄內容組成的字符串列表,例如:['1','2'....] highs = [] # 用於存儲全年每一天中的最高溫度 dates = [] # 用於存儲日期 lows = [] # 用於存儲全年每一天中的最低溫度 for row in reader: # row也是返回遍歷行的元素內容組成的字符串列表 current_date = datetime.strptime(row[0], "%Y-%m-%d") dates.append(current_date) high = int(row[1]) # 因爲前面已經next過一次了,根據reader只能被遍歷一次的性質,這裏for循環就從第二行開始遍歷 highs.append(high) # 將天天的最高溫度保存在highs列表中,這時候列表存儲的元素都是數字而非字符串,那麼咱們就能夠利用這個列表進行可視化處理了 low = int(row[3]) lows.append(low) fig = plt.figure(dpi=128, figsize=(10, 6)) 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) # 填充每日最高氣溫和最低氣溫之間的區域 plt.title("Daily high and low 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=14) plt.show()
運行結果以下:
因爲有些氣象站會偶爾出現故障,未能收集全應該收集的數據,因此若是咱們仍是採用上一個代碼例子這樣獲取某個城市的天氣數據,那麼就會報錯,由於這個城市的csv文件中某一天多是缺乏數據的,因此會報ValueError錯誤。就以下圖這樣缺乏某天的數據:
因此,鑑於上面的問題,下一節獲取死亡谷全年的天氣數據將會採用異常處理機制就能預防這種狀況。對象
前面說了可能在實際應用中可能會出現缺乏數據等問題,做爲一名程序開發者,必須設想到各類可能出現的問題,而且採用實用的方法解決問題。咱們將會採用異常處理機制來繪製死亡谷2014年每日最高氣溫和最低氣溫折線圖。代碼以下:
# 導入python支持的csv模塊,用來處理csv文件,分析csv文件中的數據行,讓咱們提取咱們感興趣的值 import csv # 導入matplotlib包裏的pyplot模塊,用於可視化獲取到的天天最高溫度 from matplotlib import pyplot as plt from datetime import datetime # 包含一個城市天氣信息的CSV文件 filename = 'death_valley_2014.csv' # 打開csv文件,實例化一個csv模塊的reader閱讀器對象 with open(filename) as f: reader = csv.reader(f) head_row = next(reader) # 返回第一行的記錄內容組成的字符串列表,例如:['1','2'....] highs = [] # 用於存儲天天最高的溫度 dates = [] # 用於存儲日期 lows = [] # 用於存儲天天最低的溫度 for row in reader: # row也是返回遍歷行的記錄內容組成的字符串列表 try: current_date = datetime.strptime(row[0], "%Y-%m-%d") high = int(row[1]) # 因爲前面已經next過一次了,根據reader只能被遍歷一次的性質,這裏for循環就從第二行開始遍歷 low = int(row[3]) except ValueError: print(current_date,'missing data') else: dates.append(current_date) highs.append(high) # 將天天的最高溫度保存在highs列表中,這時候列表存儲的元素都是數字而非字符串,那麼咱們就能夠利用這個列表進行可視化處理了 lows.append(low) fig = plt.figure(dpi=128, figsize=(10, 6)) 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) plt.title("Daily high and low temperatures,- 2014\nDeath Valley.CA", fontsize=20) plt.xlabel('', fontsize=16) fig.autofmt_xdate() plt.ylabel("Temperature (F)", fontsize=16) plt.tick_params(axis='both', which='major', labelsize=14) plt.show()
運行結果以下(兩張圖):
(1)折線圖
(2)終端圖
經過上面兩個圖能夠知道,2014-02-16這一天的溫度數據是丟失了,因此在折線圖其實沒有畫出2014-02-16這一天的最高和最低氣溫(因爲太密集看不出)。