python基础学习[python编程从入门到实践读书笔记(连载五)]:数据可视化项目第16章
文章目錄
- 下載數據
- 制作全球地震散點圖:JSON格式
- end
幾個實驗結果:
每日最高氣溫:
地震圖繪制:
下載數據
CSV文件格式
在文本文件中存儲數據,一個簡單方式是將數據作為一系列以逗號分隔的值(comma-separated values)寫入文件。這樣的文件稱為CSV文件。下面是一行CSV格式的天氣數據:
"USW00025333","SITKA AIRPORT, AK US","2018-01-01","0.45",,"48","38"CSV文件對人來說閱讀起來比較麻煩,但程序可輕松提取并處理其中的值,有助于加快數據分析過程。
在《python編程從入門到實踐》的下載資源中找到data文件夾,下面可以找到如下的csv文件,然后移動到我們的項目文件夾,如下:
分析CSV文件頭
csv模塊包含在Python標準庫中,可用于分析CSV文件中的數據行,讓我們能夠快速提取感興趣的值。先來查看這個文件的第一行,其中的一系列文件頭指出了后續各行包含的是什么樣的信息
sitka_highs.py
導入模塊csv后,將要使用的文件的名稱賦給filename。接下來,打開這個文件,并將返回的文件對象賦給f。然后,調用csv.reader()并將前面存儲的文件對象作為實參傳遞給它,從而創建一個與該文件相關聯的閱讀器對象。這個閱讀器對象被賦給了reader。
模塊csv包含函數next(),調用它并傳入閱讀器對象時,它將返回文件中的下一行。在上述代碼中,只調用了next()一次,因此得到的是文件的第一行,其中包含文件頭。將返回的數據存儲到header_row中。如你所見,header_row包含與天氣相關的文件頭,指出了每行都包含哪些數據:
['STATION', 'NAME', 'DATE', 'PRCP', 'TAVG', 'TMAX', 'TMIN']reader處理文件中以逗號分隔的第一行數據,并將每項數據都作為一個元素存儲在列表中。
- 文件頭STATION表示記錄數據的氣象站的編碼。這個文件頭的位置表明,每行的第一個值都是氣象站編碼。
- 文件頭NAME指出每行的第二個值都是記錄數據的氣象站的名稱。其他文件頭則指出記錄了哪些信息。當前,我們最關心的是日期(DATE)、最高溫度(TMAX)和最低溫度(TMIN)。
這是一個簡單的數據集,只包含降水量以及與溫度相關的數據。你自己下載天氣數據時,可選擇涵蓋眾多測量值,如風速、風向以及詳細的降水量數據。
打印文件頭及其位置
為了讓文件頭數據更容易理解,將列表中的每個文件頭及其位置打印出來:
在循環中,對列表調用了enumerate()來獲取每個元素的索引及其值。
輸出如下,指出了每個文件頭的索引:
從中可知,日期和最高溫度分別存儲在第三列和第六列。為研究這些數據,我們將處理sitka_weather-2018_simple.csv中的每行數據,并提取其中索引為2和5的值。
提取并讀取數據
知道需要哪些列中的數據后,我們來讀取一些數據。首先,讀取每天的最高溫度:
創建一個名為highs的空列表,再遍歷文件中余下的各行。
閱讀器對象從其停留的地方繼續往下讀取CSV文件,每次都自動返回當前所處位置的下一行。由于已經讀取了文件頭行,這個循環將從第二行開始——從這行開始包含的是實際數據。每次執行循環時,都將索引5處(TMAX列)的數據附加到highs末尾。
在文件中,這項數據是以字符串格式存儲的,因此在附加到highs末尾前,使用函數int()將其轉換為數值格式,以便使用。
得到的最高溫度:
[48, 48, 46, 42, 46, 44, 39, 36, 34, 28, 34, 41, 53, 63, 60, 54, 47, 46, 42, 45, 43, 41, 41, 40, 40, 41, 39, 40, 40, 39, 36, 35, 35, 34, 42, 41, 39, 42, 39, 37, 37, 40, 43, 41, 40, 38, 36, 37, 39, 39, 38, 41, 42, 41, 39, 38, 42, 39, 40, 35, 40, 41, 40, 39, 39, 40, 39, 42, 43, 44, 54, 58, 54, 45, 45, 45, 43, 41, 41, 42, 46, 42, 42, 41, 42, 43, 43, 46, 45, 43, 45, 41, 43, 45, 52, 51, 59, 52, 54, 57, 58, 51, 51, 48, 50, 49, 46, 46, 45, 45, 47, 47, 45, 46, 45, 45, 46, 47, 46, 44, 44, 47, 45, 48, 50, 56, 53, 51, 56, 52, 48, 49, 54, 45, 50, 51, 57, 52, 50, 52, 53, 52, 55, 52, 50, 52, 51, 50, 54, 53, 54, 58, 53, 57, 52, 63, 57, 59, 59, 60, 53, 51, 63, 56, 54, 60, 57, 54, 62, 67, 62, 57, 60, 57, 61, 60, 55, 56, 61, 57, 57, 62, 58, 70, 70, 67, 59, 58, 62, 66, 59, 56, 63, 65, 58, 56, 59, 64, 60, 60, 61, 65, 65, 63, 59, 64, 65, 68, 66, 64, 67, 65, 66, 59, 67, 73, 72, 64, 62, 61, 61, 63, 65, 62, 59, 61, 60, 63, 66, 63, 67, 65, 63, 59, 60, 58, 58, 63, 59, 61, 62, 61, 61, 57, 63, 62, 65, 67, 64, 65, 68, 66, 71, 69, 67, 61, 65, 62, 59, 60, 64, 63, 58, 64, 56, 56, 56, 57, 57, 57, 61, 64, 63, 66, 56, 54, 54, 57, 52, 53, 56, 54, 53, 52, 54, 56, 57, 60, 59, 55, 55, 56, 54, 56, 61, 61, 55, 55, 51, 54, 54, 55, 51, 47, 49, 45, 50, 48, 47, 46, 50, 51, 50, 47, 50, 54, 53, 49, 48, 48, 54, 52, 52, 51, 46, 47, 44, 48, 54, 53, 47, 45, 43, 39, 36, 39, 39, 41, 41, 44, 48, 52, 50, 45, 46, 43, 46, 49, 48, 48, 43, 39, 41, 44, 43, 41, 44, 46, 47, 44, 38, 42, 48]
繪制溫度圖表:
為可視化這些溫度數據,首先使用Matplotlib創建一個顯示每日最高溫度的簡單圖形,如下所示:上面asv是2018年全年的數據,下面用的是2018年7月的數據:
將最高溫度列表傳給plot(),并傳遞c='red’以便將數據點繪制為紅色。(這里使用紅色顯示最高溫度,用藍色顯示最低溫度。)接下來,設置了一些其他的格式,如名稱和字號,這些都在第15章介紹過。鑒于還沒有添加日期,因此沒有給x軸添加標簽,但ax.set_xlabel()確實修改了字號,讓默認標簽更容易看清。
繪圖結果:
模塊datatime
下面在圖表中添加日期,使其更有用。在天氣數據文件中,第一個日期在第二行
USW00025333 SITKA AIRPORT, AK US 2018/1/1 0.45 48 38讀取該數據時,獲得的是一個字符串,因此需要想辦法將字符串"2018/1/1"轉換為一個表示相應日期的對象。為創建一個表示2018年1月1日的對象,可使用模塊datetime中的方法strptime()。我們在終端會話中看看strptime()的工作原理:
首先導入模塊datetime中的datetime類,再調用方法strptime(),并將包含所需日期的字符串作為第一個實參。第二個實參告訴Python如何設置日期的格式。在這里,’%Y/‘讓Python將字符串中第一個連字符前面的部分視為四位的年份,’%m/‘讓Python將第二個連字符前面的部分視為表示月份的數,’%d’讓Python將字符串的最后一部分視為月份中的一天(1~31)。
需要注意的是:“%Y”后面的符號需要和文件匹配,這里用的是/,而要處理asv文件的時候,這里需要變成“%Y-”. 請參考后面的代碼。
方法strptime()可接受各種實參,并根據它們來決定如何解讀日期。
在圖表中添加日期
現在,可以通過提取日期和最高溫度并將其傳遞給plot(),對溫度圖形進行改進,如下所示:
import csv from datetime import datetimeimport matplotlib.pyplot as pltfilename = '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)# 根據最高溫度繪制圖形 plt.style.use('seaborn') plt.rcParams['font.sans-serif'] = ['SimHei'] fig, ax = plt.subplots() ax.plot(dates, highs, c='red')# 設置圖形格式 ax.set_title("2018年7月每日最高溫度", fontsize=24) ax.set_xlabel('', fontsize=16) fig.autofmt_xdate() ax.set_ylabel("溫度(F)", fontsize=16) ax.tick_params(axis='both', which='major', labelsize=16)plt.show()我們創建了兩個空列表,用于存儲從文件中提取的日期和最高溫度。然后,將包含日期信息的數據(row[2])轉換為datetime對象,并將其附加到列表dates末尾。然后,將日期和最高溫度值傳遞給plot()。調用fig.autofmt_xdate()來繪制傾斜的日期標簽,以免其彼此重疊.
涵蓋更長的時間
設置好圖表后,我們來添加更多的數據,生成一幅更復雜的錫特卡天氣圖。請將文件sitka_weather_2018_simple.csv復制到本章程序所在的文件夾,該文件包含整年的錫特卡天氣數據。
代碼
import csv from datetime import datetimeimport matplotlib.pyplot as plt# filename = 'data/sitka_weather_07-2018_simple.csv' 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)# 根據最高溫度繪制圖形 plt.style.use('seaborn') plt.rcParams['font.sans-serif'] = ['SimHei'] fig, ax = plt.subplots() ax.plot(dates, highs, c='red')# 設置圖形格式 ax.set_title("2018年每日最高溫度", fontsize=24) ax.set_xlabel('', fontsize=16) fig.autofmt_xdate() ax.set_ylabel("溫度(F)", fontsize=16) ax.tick_params(axis='both', which='major', labelsize=16)plt.show()再繪制一個數據系列
雖然改進后的圖表已經顯示了豐富的數據,但是還能再添加最低溫度數據,使其更有用。為此,需要從數據文件中提取最低溫度,并將它們添加到圖表中,如下所示:
sikta_highs_lows.py
import csv from datetime import datetimeimport matplotlib.pyplot as plt# filename = 'data/sitka_weather_07-2018_simple.csv' 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)# 根據最高溫度和最低溫度繪制圖形 plt.style.use('seaborn') plt.rcParams['font.sans-serif'] = ['SimHei'] fig, ax = plt.subplots() ax.plot(dates, highs, c='red') ax.plot(dates, lows, c='blue')# 設置圖形格式 ax.set_title("2018年每日最高溫度", fontsize=24) ax.set_xlabel('', fontsize=16) fig.autofmt_xdate() ax.set_ylabel("溫度(F)", fontsize=16) ax.tick_params(axis='both', which='major', labelsize=16)plt.show()繪制的結果:
給圖表區域著色
添加兩個數據系列后,就可以知道每天的溫度范圍了。下面來給這個圖表做最后的修飾,通過著色來呈現每天的溫度范圍。為此,將使用方法fill_between()。它接受一個x值系列和兩個y值系列,并填充兩個y值系列之間的空間:
ax.plot()處的實參alpha指定顏色的透明度。alpha值為0表示完全透明,為1(默認設置)表示完全不透明。通過將alpha設置為0.5,可讓紅色和藍色折線的顏色看起來更淺。
另外,向fill_between()傳遞一個x值系列(列表dates),以及兩個y值系列(highs和lows)。實參facecolor指定填充區域的顏色,還將alpha設置成了較小的值0.1,讓填充區域將兩個數據系列連接起來的同時不分散觀察者的注意力。下圖顯示了最高溫度和最低溫度之間的區域被填充后的圖表。
錯誤檢查
有些氣象站收集的數據種類不同,有些氣象站會偶爾出現故障,未能收集部分或全部應收集的數據。缺失數據可能引發異常,如果不妥善處理,可能導致程序崩潰。例如,來看看生成加利福尼亞州死亡谷的溫度圖時出現的情況。
death_valley_highs.py
import csvfilename = '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)輸出如下
0 STATION 1 NAME 2 DATE 3 PRCP 4 TMAX 5 TMIN 6 TOBS與前面一樣,日期也在索引2處,但最高溫度和最低溫度分別在索引4和索引5處,因此需要修改代碼中的索引,以反映這一點。另外,這個氣象站沒有記錄平均溫度,而記錄了TOBS,即特定時點的溫度。
import csv from datetime import datetime from matplotlib import pyplot as pltfilename = '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)運行上述代碼,會報錯
Traceback (most recent call last):File "death_valley_highs_lows.py", line 14, in <module>high = int(row[4]) ValueError: invalid literal for int() with base 10: ''traceback指出,Python無法處理其中一天的最高溫度,因為無法將空字符串(’’)轉換為整數。我們只要看一下文件death_valley_2018_simple.csv,就知道缺失了哪項數據,但這里不這樣做,而是直接對缺失數據的情形進行處理。
下面的代碼使用了python的格式化輸出:使用 格式化字符串字面值 ,要在字符串開頭的引號或三引號前添加 f 或 F 。在這種字符串中,可以在 { 和 } 字符之間輸入引用的變量,或字面值的 Python 表達式。
death_valley_highs_lows.py
import csv from datetime import datetime from matplotlib import pyplot as pltfilename = '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)# 根據最低氣溫和最高氣溫繪制圖形 plt.style.use('seaborn') plt.rcParams['font.sans-serif'] = ['SimHei']fig, ax = plt.subplots() ax.plot(dates, highs, c='red', alpha=0.5) ax.plot(dates, lows, c='blue', alpha=0.5) plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)# 設置圖形的格式 title = "2018年每日最高溫度和最低溫度\n美國加利福尼亞州死亡谷" ax.set_title(title, fontsize=20) ax.set_xlabel('', fontsize=16)plt.ylabel("Temperature (F)", fontsize=16) plt.tick_params(axis='both', which='major', labelsize=16)plt.show()對于每一行,都嘗試從中提取日期、最高溫度和最低溫度。
只要缺失其中一項數據,Python就會引發ValueError異常。我們這樣進行處理:打印一條錯誤消息,指出缺失數據的日期。
打印錯誤消息后,循環將接著處理下一行。如果獲取特定日期的所有數據時沒有發生錯誤,就運行else代碼塊,將數據附加到相應列表的末尾。
這里繪圖時使用的是有關另一個地方的信息,因此修改標題以指出這個地方。因為標題更長,所以我們縮小了字號。
下面是遺失數據產生的錯誤信息,這里可以看出,上面的數據集中只有1條有誤的數據。
Missing data for 2018-02-18 00:00:00使用的很多數據集都可能缺失數據、格式不正確或數據本身不正確。對于這樣的情形,在這里,使用了一個try-except-else代碼塊來處理數據缺失的問題。在有些情況下,需要使用continue來跳過一些數據,或者使用remove()或del將已提取的數據刪除。只要能進行精確而有意義的可視化,采用任何管用的方法都是可以的。
制作全球地震散點圖:JSON格式
數據集中記錄了一個月內全球發生的所有地震,再制作一幅散點圖來展示這些地震的位置和震級。其中,這些數據是json數據,需要用到的是json模塊。
地震數據
打開json數據之后,我們發現這些數據格式統一,但是不適合人來閱讀,其實,這樣格式化的數據特別適合機器來讀。
模塊json提供了各種探索和處理JSON數據的工具,其中一些有助于重新設置這個文件的格式,讓我們能夠更清楚地查看原始數據,繼而決定如何以編程的方式來處理。
eq_explore_data.py
首先導入模塊json,以便恰當地加載文件中的數據,并將其存儲到all_eq_data中。函數json.load()將數據轉換為Python能夠處理的格式,這里是一個龐大的字典。創建一個文件,以便將這些數據以易于閱讀的方式寫入其中。
函數json.dump()接受一個JSON數據對象和一個文件對象,并將數據寫入這個文件中。參數indent=4讓dump()使用與數據結構匹配的縮進量來設置數據的格式。
我們來查看現在的json文件,部分內容如下:
{"type": "FeatureCollection","metadata": {"generated": 1550361461000,"url": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_day.geojson","title": "USGS Magnitude 1.0+ Earthquakes, Past Day","status": 200,"api": "1.7.0","count": 158},"features": [這個文件的開頭是一個鍵為"metadata"的片段(第二行),指出了這個數據文件是什么時候生成的,以及能夠在網上的什么地方找到。它還包含適合人類閱讀的標題以及文件中記錄了多少次地震:在過去的24小時內,發生了158次地震。
這個geoJSON文件的結構適合存儲基于位置的數據。數據存儲在一個與鍵"features"相關聯的列表中。這個文件包含的是地震數據,因此列表的每個元素都對應一次地震。這種結構可能有點令人迷惑,但很有用,讓地質學家能夠將有關每次地震的任意數量信息存儲在一個字典中,再將這些字典放在一個大型列表中。
下圖是feature列表中的一項,含義是一次具體的地震。
鍵"properties"關聯到了與特定地震相關的大量信息。我們關心的主要是與鍵"mag"相關聯的地震震級以及地震的標題,因為后者很好地概述了地震的震級和位置。
鍵"geometry"指出了地震發生在什么地方,我們需要根據這項信息將地震在散點圖上標出來。在與鍵"coordinates"相關聯的列表中,可找到地震發生位置的經度和緯度。
這里有一點值得注意的地方,《python編程從入門到實踐》指出:
注意:說到位置時,我們通常先說緯度、再說經度,這種習慣形成的原因可能是人類先發現了緯度,很久后才有經度的概念。然而,很多地質學框架都先列出經度、后列出緯度,因為這與數學約定(x,y)一致。geoJSON格式遵循(經度, 緯度)的約定,但在使用其他框架時,獲悉其遵循的約定很重要。
創建地震列表
首先,創建一個列表,其中包含所有地震的各種信息:
我們提取與鍵’features’相關聯的數據,并將其存儲到all_eq_dicts中。我們知道,這個文件記錄了158次地震。下面的輸出表明,我們提取了這個文件記錄的所有地震:
import json# 探索數據的結構 filename = 'data/eq_data_1_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)""" readable_file = 'data/readable_json_data.json' with open(readable_file, 'w') as f:json.dump(all_eq_data, f, indent=4) """ all_eq_dicts = all_eq_data['features'] print(len(all_eq_dicts))運行之,程序會輸出158,表示這個文件中總共記錄了158次地震信息。
提取震級
有了包含所有地震數據的列表后,就可遍歷這個列表,從中提取所需的數據。下面來提取每次地震的震級:
import json# 探索數據的結構 filename = 'data/eq_data_1_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)""" readable_file = 'data/readable_json_data.json' with open(readable_file, 'w') as f:json.dump(all_eq_data, f, indent=4) """all_eq_dicts = all_eq_data['features']mags = [] for eq_dict in all_eq_dicts:mag = eq_dict['properties']['mag']mags.append(mag)print(mags[:10])我們創建了一個空列表,用于存儲地震震級,再遍歷列表all_eq_dicts。每次地震的震級都存儲在相應字典的’properties’部分的’mag’鍵下。我們依次將地震震級賦給變量mag,再將這個變量附加到列表mags末尾。
為確定提取的數據是否正確,打印前10次地震的震級:
[0.96, 1.2, 4.3, 3.6, 2.1, 4, 1.06, 2.3, 4.9, 1.8]提取位置數據
位置數據存儲在"geometry"鍵下。在"geometry"鍵關聯的字典中,有一個"coordinates"鍵,它關聯到一個列表,而列表中的前兩個值為經度和緯度。下面演示了如何提取位置數據:
import json# 探索數據的結構 filename = 'data/eq_data_1_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)""" readable_file = 'data/readable_json_data.json' with open(readable_file, 'w') as f:json.dump(all_eq_data, f, indent=4) """all_eq_dicts = all_eq_data['features']mags, titles, lons, lats = [], [], [], [] for eq_dict in all_eq_dicts:mag = eq_dict['properties']['mag']title = eq_dict['properties']['title']lon = eq_dict['geometry']['coordinates'][0]lat = eq_dict['geometry']['coordinates'][1]mags.append(mag)titles.append(title)lons.append(lon)lats.append(lat)print(mags[:10]) print(titles[:2]) print(lons[:5]) print(lats[:5])我們創建了用于存儲位置標題的列表titles,來提取字典’properties’里’title’鍵對應的值,以及用于存儲經度和緯度的列表。代碼eq_dict['geometry']訪問與"geometry"鍵相關聯的字典。第二個鍵(‘coordinates’)提取與"coordinates"相關聯的列表,而索引0提取該列表中的第一個值,即地震發生位置的經度。
輸出結果
[0.96, 1.2, 4.3, 3.6, 2.1, 4, 1.06, 2.3, 4.9, 1.8] ['M 1.0 - 8km NE of Aguanga, CA', 'M 1.2 - 11km NNE of North Nenana, Alaska'] [-116.7941667, -148.9865, -74.2343, -161.6801, -118.5316667] [33.4863333, 64.6673, -12.1025, 54.2232, 35.3098333]對應的代碼是
print(mags[:10]) # 地震等級 print(titles[:2]) # 地震名稱 print(lons[:5]) # 經度 print(lats[:5]) # 緯度繪制震級散點圖
首先要實現繪制一個簡單的散點圖。
運行書中代碼得到的圖形:
這和書上顯示的不太一樣啊,暈,我還以為我做錯了!后來才發現,根據書中的代碼,這才是繪制出來的結果,因為根本沒用地圖。
書上的圖:(坑了我!)
另一種指定圖表數據的方式
使用pandas數據分析工具。創建一個DataFrame,將需要的數據封裝起來:
# plotly express 是Plotly的高級接口 import plotly.express as px import json import pandas as pdfilename = 'data/eq_data_1_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)all_eq_dicts = all_eq_data['features'] mags, titles, lons, lats = [], [], [], [] for eq_dict in all_eq_dicts:mag = eq_dict['properties']['mag']title = eq_dict['properties']['title']lon = eq_dict['geometry']['coordinates'][0]lat = eq_dict['geometry']['coordinates'][1]mags.append(mag)titles.append(title)lons.append(lon)lats.append(lat) # 使用DataFrame將數據封裝 # 所有有關數據的信息都以鍵值對的方式存在字典中。 data = pd.DataFrame(data = zip(lons, lats, titles, mags), columns = ["經度","緯度","位置","震級"], )data.head()# 調用px.scatter函數配置參數創建一個fig實例 fig = px.scatter(data,x="經度",y="緯度",labels = {"x": "經度", "y": "緯度"},range_x = [-200, 200],range_y = [-90, 90],width = 800,height = 800,title = "全球地震散點圖" )# fig.write_html 可以將可視化圖保存為html文件 fig.write_html("global_earthquakes.html") fig.show()運行代碼,我們得到的是和上面繪圖同樣的結果:
然后根據參考博客:《Python 編程:從入門到實踐》16章 地圖部分練習 提供的繪制方式:將px.scatter替換成px.density_mapbox,然后就得到下面的繪制結果:
# 調用px.scatter函數配置參數創建一個fig實例 """ fig = px.scatter(data,x="經度",y="緯度",labels = {"x": "經度", "y": "緯度"},range_x = [-200, 200],range_y = [-90, 90],width = 800,height = 800,title = "全球地震散點圖" )"""fig = px.density_mapbox(data, lat='緯度', lon='經度', z='震級', hover_name='位置', radius=5,center=dict(lat=0, lon=180), zoom=0, mapbox_style="stamen-terrain")代碼如下:
# plotly express 是Plotly的高級接口 import plotly.express as px import json import pandas as pdfilename = 'data/eq_data_1_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)all_eq_dicts = all_eq_data['features'] mags, titles, lons, lats = [], [], [], [] for eq_dict in all_eq_dicts:mag = eq_dict['properties']['mag']title = eq_dict['properties']['title']lon = eq_dict['geometry']['coordinates'][0]lat = eq_dict['geometry']['coordinates'][1]mags.append(mag)titles.append(title)lons.append(lon)lats.append(lat)data = pd.DataFrame(data = zip(lons, lats, titles, mags), columns = ["經度","緯度","位置","震級"], )data.head()# 調用px.scatter函數配置參數創建一個fig實例 """ fig = px.scatter(data,x="經度",y="緯度",labels = {"x": "經度", "y": "緯度"},range_x = [-200, 200],range_y = [-90, 90],width = 800,height = 800,title = "全球地震散點圖" )"""fig = px.density_mapbox(data, lat='緯度', lon='經度', z='震級', hover_name='位置', radius=5,center=dict(lat=0, lon=180), zoom=0, mapbox_style="stamen-terrain")# fig.write_html 可以將可視化圖保存為html文件 fig.write_html("global_earthquakes.html") fig.show()定制標記的顏色
定制顏色,以呈現地震的嚴重程度。這里換成了更大的數據集,用的是30天的。
未定制標記之前
加了顏色定制之后的運行結果
了讓標記的震級按照不同的顏色顯示,只需要配置color="震級"即可。默認的視覺映射圖例漸變色范圍是從藍到紅再到黃,數值越小則標記越藍,而數值越大則標記越黃。
代碼:
# plotly express 是Plotly的高級接口 import plotly.express as px import json import pandas as pdfilename = 'data/eq_data_30_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)all_eq_dicts = all_eq_data['features'] mags, titles, lons, lats = [], [], [], [] for eq_dict in all_eq_dicts:mag = eq_dict['properties']['mag']title = eq_dict['properties']['title']lon = eq_dict['geometry']['coordinates'][0]lat = eq_dict['geometry']['coordinates'][1]mags.append(mag)titles.append(title)lons.append(lon)lats.append(lat)data = pd.DataFrame(data = zip(lons, lats, titles, mags), columns = ["經度","緯度","位置","震級"], )data.head()# 調用px.scatter函數配置參數創建一個fig實例fig = px.scatter(data,x="經度",y="緯度",labels = {"x": "經度", "y": "緯度"},range_x = [-200, 200],range_y = [-90, 90],width = 800,height = 800,title = "全球地震散點圖",size_max = 10,color = '震級', )"""fig = px.density_mapbox(data, lat='緯度', lon='經度', z='震級', hover_name='位置', radius=5,center=dict(lat=0, lon=180), zoom=0, mapbox_style="stamen-terrain")"""# fig.write_html 可以將可視化圖保存為html文件 fig.write_html("global_earthquakes.html") fig.show()使用繪制地圖的api:
# plotly express 是Plotly的高級接口 import plotly.express as px import json import pandas as pdfilename = 'data/eq_data_30_day_m1.json' with open(filename) as f:all_eq_data = json.load(f)all_eq_dicts = all_eq_data['features'] mags, titles, lons, lats = [], [], [], [] for eq_dict in all_eq_dicts:mag = eq_dict['properties']['mag']title = eq_dict['properties']['title']lon = eq_dict['geometry']['coordinates'][0]lat = eq_dict['geometry']['coordinates'][1]mags.append(mag)titles.append(title)lons.append(lon)lats.append(lat)data = pd.DataFrame(data = zip(lons, lats, titles, mags), columns = ["經度","緯度","位置","震級"], )data.head()# 調用px.scatter函數配置參數創建一個fig實例 """ fig = px.scatter(data,x="經度",y="緯度",labels = {"x": "經度", "y": "緯度"},range_x = [-200, 200],range_y = [-90, 90],width = 800,height = 800,title = "全球地震散點圖",size_max = 10,color = '震級', )"""fig = px.density_mapbox(data, lat='緯度', lon='經度', z='震級', hover_name='位置', radius=5,center=dict(lat=0, lon=180), zoom=0, mapbox_style="stamen-terrain")# fig.write_html 可以將可視化圖保存為html文件 fig.write_html("global_earthquakes.html") fig.show()使用density_mapbox運行結果:
關于density_mapbox的官方文檔:https://plotly.com/python/mapbox-density-heatmaps/
https://plotly.com/python-api-reference/generated/plotly.express.density_mapbox
plotly.express.density_mapbox(data_frame=None, lat=None, lon=None, z=None, hover_name=None, hover_data=None, custom_data=None, animation_frame=None, animation_group=None, category_orders=None, labels=None, color_continuous_scale=None, range_color=None, color_continuous_midpoint=None, opacity=None, zoom=8, center=None, mapbox_style=None, radius=None, title=None, template=None, width=None, height=None)
end
總結
以上是生活随笔為你收集整理的python基础学习[python编程从入门到实践读书笔记(连载五)]:数据可视化项目第16章的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python遇到Retry(total=
- 下一篇: python基础学习[python编程从