分級著色圖(Choropleth Map)將資料的變量以視覺化的方式顯示在地圖上。我們在本文章中將介紹如何用 Python 的 Plotly Express 套件來繪製分級著色圖。
Table of Contents
Plotly Express
Plotly Express 的 choropleth() 讓我們可以很簡單的繪製分級著色圖。以下是它的宣告。其餘的參數,請參照官網。
plotly.express.choropleth(data_frame=None, locations=None, locationmode=None, color=None, color_discrete_map=None, color_continuous_scale=None, projection=None, scope=None, title=None)
- data_frame:資料。
- locationmode:可以是 ‘ISO-3’、’USA-states’、或 ‘country names’。
- locations:其資料會依據參數 locationmode 指定的格式來解讀。值為 data_frame 的欄位名稱。
- color:其資料的數值會被作為依據來決定顏色。值為 data_frame 的欄位名稱。
- scope:地圖的區域。可以是 ‘world’、’usa’、’europe’、’asia’、’africa’、’north america’、或 ‘south america’。預設為 ‘world’。
- projection:地圖投影的方式。請參照官網其可設定的值。
- title:圖表的標題。
- color_continuous_scale:地圖上顏色所用的 color map。
- color_discrete_map:地圖上顏色所用的 color map。
- color_discrete_sequence:地圖上顏色所用的 color map。
範例的資料集
本文章的範例中,我們將使用 Plotly Express 的兩個資料集。讓我們來看看如何讀取這些資料集,以及它們的資料結構。
第一個資料集是 2014 年世界各國的 GDP。
import pandas as pd df_gdp = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv') df_gdp.head()
COUNTRY | GDP (BILLIONS) | CODE |
---|---|---|
Afghanistan | 21.71 | AFG |
Albania | 13.40 | ALB |
Algeria | 227.80 | DZA |
American Samoa | 0.75 | ASM |
Andorra | 4.80 | AND |
另外一個資料集是 2014 年美國各州的人口數。
df_us_state = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_usa_states.csv') df_us_state.head()
Rank | State | Postal | Population |
---|---|---|---|
1 | Alabama | AL | 4849377.0 |
2 | Alaska | AK | 736732.0 |
3 | Arizona | AZ | 6731484.0 |
4 | Arkansas | AR | 2966369.0 |
5 | California | CA | 38802500.0 |
範例
以下的範例是 choropleth() 基本的使用範例。
import plotly.express as px px.choropleth(df_gdp, locations='COUNTRY', locationmode='country names', color='GDP (BILLIONS)', projection='kavrayskiy7', scope='world', title='World GDP')
參數 scope 指定使用世界地圖,而且參數 projection 使用 kavrayskiy7 投影。參數 locationmode 是 'country names'
,這告訴 choropleth() 參數 locations 裡的資料是國家名稱。最後,choropleth() 會依據參數 color 裡的數值來對每個國家填入顏色。
Continuous Color Scales
我們可以在參數 color_continuous_scale 傳入不同的 color map 給 choropleth() ,這樣我們就可以用不同的顏色來繪製分級著色圖。Plotly Express 已經內建數個 continuous color scalers,我們可以選我們喜歡的顏色。
這些內建的顏色分佈在三個模組。
- plotly.colors.sequential:適合於大部分的連續資料(continuous data)。
- plotly.colors.diverging:適合於那些有 midpoint 的連續資料。
- plotly.colors.cyclical:適合於那些有循環結構(cyclical structure)的連續資料。
- plotly.colors.named_colorscales:預先定義的 continuous color scale 名稱。這些名稱會對應到以上三個裡的一些 continuous color scale。
此外,如果你想要反轉顏色順序的話,只要在顏色後面加上 _r
就可以了。
讓我們來看以下的範例。
px.choropleth(df_gdp, locations='COUNTRY', locationmode='country names', color='GDP (BILLIONS)', projection='kavrayskiy7', scope='world', title='Choropleth Map', color_continuous_scale=px.colors.sequential.Rainbow)
範例中我們傳入 px.colors.sequential.Rainbow
給參數 color_continuous_scale,我們就可以用 Rainbow 的顏色。如果想要反轉顏色順序的話,那就傳入 px.colors.sequential.Rainbow_r
即可。
下面的範例顯示如何使用 named continuous color scales。
px.choropleth(df_gdp, locations='COUNTRY', locationmode='country names', color='GDP (BILLIONS)', projection='kavrayskiy7', scope='world', title='Choropleth Map', color_continuous_scale='jet_r')
jet
是預先定義好的 continuous color scales,而它的反轉就是 jet_r
。實際上,jet
是對應到 px.colors.sequential.Jet
。
Discrete Colors
除了 continuous color scales 之外,我們也可以使用不連續的顏色來區分等級或是階層。Plotly Express 已經有預先定義一些 discrete colors 在 plotly.colors.qualitative 模組。這些都是一個含有一連串 CSS 顏色代碼的 array。
我們可以傳入一個 dictionary 給參數 color_discrete_map。在這個 dictionary 中,指定每個值的對應顏色。其範例如下。
colors = px.colors.qualitative.Set2 population_max = df_us_state['Population'].max() def group_population(x): y = int(population_max / 5) if x < y: return '{}~{}'.format(0, y) elif x < y * 2: return '{}~{}'.format(y, y*2) elif x < y * 3: return '{}~{}'.format(y*2, y*3) elif x < y * 4: return '{}~{}'.format(y*3, y*4) else: return '{}~{}'.format(y*4, y*5) df_us_state['Population (Grouped)'] = df_us_state['Population'].apply(group_population) px.choropleth(df_us_state, locations='Postal', locationmode='USA-states', scope='usa', color='Population (Grouped)', color_discrete_map=dict(zip(df_us_state['Population (Grouped)'].unique(), colors)))
範例中我們將 Population
欄位的資料分成 5 群,並將群的標籤存在 Population (Grouped)
欄位裡。然後,用 zip() 將群和顏色對應成一個 tuple 的 array。最後,用 dict() 將一連串的 tuple 轉成 dictionary,然後傳給參數 color_discrete_map。
另外,如果你不喜歡用 dictionary 的話,我們可以改傳入一個顏色的 array 給參數 color_discrete_sequence。
px.choropleth(df_us_state, locations='Postal', locationmode='USA-states', scope='usa', color='Population (Grouped)', color_discrete_sequence=colors)
結論
在將資料視覺化時,我們可能會需要使用到分級著色圖。如果使用 Matplotlib Basemap 來繪製分級著色圖的話,真的會花費不少時間。所幸 Plotly Express 提供了這麼方便的函式讓我們可以輕鬆地繪製圖表,而且繪製出來的圖表還相當的漂亮。