使用Pandas,Seaborn和Plotly繪製漂亮的圖表

完整的代碼以及Python可視化指南,介紹了Pandas,Seaborn和Plotly的繪圖。

1

2018: Regplot showing how Life Ladder (Happiness) is positively correlated with Log GDP per capita (

在今天的文章中,我們將研究使用Python繪製數據的三種不同方式。 我們將通過利用《 2019年世界幸福報告》中的數據來做到這一點。我用Gapminder和Wikipedia的信息豐富了《世界幸福報告》數據,以便探索新的關係和可視化。

《世界幸福報告》試圖回答哪些因素影響着全世界的幸福。

報告中的幸福定義爲對" Cantril階梯問題"的回答,要求被調查者以0到10的等級來評價他們今天的生活,最糟糕的爲0,最好的爲10。

在整篇文章中,我將使用Life Ladder作爲目標變量。 每當我們談論人生階梯時,請思考幸福是什麼。


本文旨在作爲代碼指南,以及當您要查找特定類型的圖時重新訪問的參考。 爲了節省空間,我有時會將多個圖表合併爲一張圖像。 但是請放心,您可以在此(https://github.com/FBosler/AdvancedPlotting)或相應的Jupyter Notebook中找到所有基礎代碼。

目錄

· 我的Python繪圖歷史

· 分佈的重要性

· 加載數據和包導入

· 快速:使用Pandas進行基本繪圖

· 漂亮:與Seaborn的高級繪圖

· 很棒:使用plotly創建出色的交互式圖


我使用Python繪圖的歷史

大約兩年前,我開始更認真地學習Python。 從那以後,幾乎沒有一個星期不讓我驚歎於Python本身,或生態系統中衆多令人驚歎的開源庫的簡單性和易用性。 我熟悉的命令,模式和概念越多,那麼所有事情就越有意義。

Matplotlib

使用Python進行繪圖的情況恰恰相反。 最初,我用Matplotlib創建的幾乎每個圖表都看起來像是八十年代逃脫的罪犯。 更糟糕的是,要創建這些可憎的東西,我通常不得不在Stackoverflow上花費數小時。 例如,研究nitty-gritty命令以更改x-ticks的傾斜度或類似的愚蠢行爲。 甚至沒有讓我開始使用多張圖表。 結果看起來令人印象深刻,並且以編程方式創建這些圖表是一種奇妙的感覺。 例如,一次生成50個針對不同變量的圖表。 但是,這只是很多工作,需要您記住很多其他本來沒用的命令。

Seaborn

瞭解Seaborn是一種解脫。 Seaborn提取了許多微調。 毫無疑問,最終圖表的美學意義是一個巨大的飛躍。 但是,它也是基於Matplotlib構建的。 通常,對於非標準調整,仍然有必要深入瞭解機器級的matplotlib代碼。

Bokeh

簡要了解一下Bokeh,我以爲Bokeh將成爲我的首選解決方案。 當我從事地理空間可視化工作時遇到了Bokeh。 但是,我很快意識到,雖然Bokeh與衆不同,但它與matplotlib一樣複雜。

Plotly

我確實在一段時間前嘗試了plot.ly(從現在開始被稱爲plotly)。 再一次,致力於地理空間數據的可視化。 那時,它似乎比前面提到的庫還要不靠譜。需要一個帳戶,必須通過筆記本電腦登錄,然後才能使所有內容在線呈現。 然後,還需要下載結果圖表。 我迅速放棄了。 但是,最近,我看了一個有關YouTube的視頻,該視頻關於plotly express和plotly 4.0,最重要的是,他們擺脫了所有這些在線限制。 我玩了一下,這篇文章就是它的結果。 我想遲到總比沒有好。

Kepler.gl(地理空間數據榮譽獎)

Kepler.gl雖然絕對不是Python庫,但它是一種用於地理空間數據的基於Web的強大可視化工具。 您只需要CSV文件,即可使用Python輕鬆創建。 試試看!

我目前的工作流程

最終,我決定使用Pandas原始繪圖進行快速檢查,並使用Seaborn生成要在報告和演示文稿中使用的圖表(視覺效果很重要)。


分佈的重要性

在聖地亞哥學習期間,我教過統計學(Stats 119)。 統計119是統計的入門課程。 該課程包括統計基礎,例如數據彙總(可視和定量),機率和概率的概念,迴歸,抽樣以及最重要的分佈。 這次是我對數量和現象的理解幾乎全部轉變爲基於分佈表示(大部分時間是高斯)。

時至今日,我發現這兩個數量的平均含義令人吃驚,而標準偏差可以幫助您把握現象。 僅通過了解這兩個數字,就可以輕鬆得出特定結果的可能性。 人們立即知道大部分結果將在哪裏。 它爲您提供了一個參考框架,可以快速將軼事與有統計意義的事件區分開來,而無需進行過於複雜的計算。

一般而言,面對新數據時,我的第一步是嘗試可視化其分佈,以更好地理解數據。


加載數據和導入庫

讓我們加載本文中將要使用的數據。 我確實對數據進行了一些預處理。 我在有意義的地方進行數據填充處理。

# Load the data data = pd.read_csv('https://raw.githubusercontent.com/FBosler/AdvancedPlotting/master/combined_set.csv') 
# this assigns labels per year 
data['Mean Log GDP per capita'] = data.groupby('Year')['Log GDP per capita'].transform( pd.qcut, q=5, labels=(['Lowest','Low','Medium','High','Highest']) )

數據集包含以下各列的值:

· Year 年:計量年(從2007年到2018年)

· Life Ladder 人生階梯:受訪者根據Cantril階梯,以0到10的等級(10最佳)衡量他們今天的生活價值

· Log GDP per capita 對數人均GDP:根據購買力平價(PPP)調整的人均GDP,根據世界銀行於2018年11月14日發佈的世界發展指標(WDI)得出

· Social support 社會支持:對問題的回答:“如果遇到麻煩,您是否有親戚或朋友可以在需要時幫助您?”

· Healthy life expectancy at birth 出生時的健康預期壽命:出生時的預期壽命是根據世界衛生組織(WHO)全球衛生觀察站數據存儲庫中的數據構建的,其中提供了2005、2010、2015和2016年的數據。

· Freedom to make life choices 選擇生活的自由度:對問題的回答:“您對選擇自己的生活的自由感到滿意還是不滿意?”

· Generosity 慷慨度:與"人均GDP"相比,對"您在過去一個月向慈善機構捐款了嗎?"的迴應

· Perceptions of corruption 對腐敗的看法:回答"腐敗是否在整個政府範圍內廣泛存在?“和"腐敗是否在企業內部廣泛分佈?”

· Positive affect 積極影響:包括前一天的幸福,笑聲和享受的平均頻率。

· Negative affect 負面影響:包括前一天擔憂,悲傷和憤怒的平均頻率。

· Confidence in national government 對國家政府的信心:不言自明

· Democratic Quality 民主素質:一個國家的民主程度

· Delivery Quality 交付質量:一個國家兌現其政策的效果如何

· Gapminder Life Expectancy Gapminder預期壽命:Gapminder的預期壽命

· Gapminder Population Gapminder人口:一個國家的人口

庫加載

import plotly 
import pandas as pd 
import numpy as np import seaborn as sns 
import plotly.express as px import matplotlib 
%matplotlib inline 
assert matplotlib.__version__ == "3.1.0",
""" 
Please install matplotlib version 3.1.0 by running: 
1) !pip uninstall matplotlib 
2) !pip install matplotlib==3.1.0 
"""

快速:使用Pandas進行基本繪圖

Pandas具有內置的繪圖功能,可以在Series或DataFrame上調用它。 我喜歡這些繪圖功能,因爲它們簡潔,使用合理的默認值,並且可以快速瞭解發生的情況。

要創建繪圖,請對數據調用.plot(kind = ),如下所示:

np.exp(data[data['Year']==2018]['Log GDP per capita']).plot( kind='hist' )

運行上面的命令將產生以下圖表。

2

2018: Histogram of the number of countries per GDP per Capita bucket. Not surprisingly, most countri

使用Pandas進行繪圖時,有五個主要參數:

· kind:Pandas必須知道您要創建哪種圖,以下選項可用hist,bar,barh,scatter,area,kde,line,box,hexbin,餅圖。

· figsize:允許覆蓋6英寸寬和4英寸高的默認輸出大小。 figsize需要一個元組(例如,我經常使用的figsize =(12,8))

· title:向圖表添加標題。 在大多數情況下,我用它來澄清圖表中顯示的內容,以便當我回到圖表上時,可以快速確定發生了什麼。 title需要一個字符串。

· bins:允許覆蓋直方圖的bin寬度。 bins需要一個列表或類似列表的值序列(例如bins = np.arange(2,8,0.25))

· xlim / ylim:允許覆蓋軸的最大值和最小值的默認值。 xlim和ylim都期望有一個元組(例如xlim =(0,5))

讓我們快速瀏覽各種可用的plots類型。

垂直條形圖

data[ data['Year'] == 2018 ]
.set_index('Country name')['Life Ladder']
.nlargest(15)
.plot( kind='bar', figsize=(12,8) )

3

2018: List of 15 happiest countries is led by Finnland

水平條形圖

np.exp(data[ data['Year'] == 2018 ]
.groupby('Continent')['Log GDP per capita']
.mean()).sort_values()
.plot( kind='barh', figsize=(12,8) )

!4

Average GDP per capita by continent in 2011 USD Dollars clearly led by Australia and New Zealand

箱形圖

data['Life Ladder'].plot( kind='box', figsize=(12,8) )

5

Box plot of the distribution of Life Ladder shows that the median is somewhere around 5.5 ranging fr

散點圖

data[['Healthy life expectancy at birth','Gapminder Life Expectancy']]
.plot( 
kind='scatter', 
x='Healthy life expectancy at birth', 
y='Gapminder Life Expectancy', 
figsize=(12,8) )

6

Scatter plot of the World Happiness Report life expectation against the Gapminder life expectation s

六邊形圖

data[data['Year'] == 2018]
.plot( kind='hexbin', 
  x='Healthy life expectancy at birth', 
  y='Generosity', 
  C='Life Ladder', 
  gridsize=20, 
  figsize=(12,8),  
  cmap="Blues", # defaults to greenish 
  sharex=False # required to get rid of a bug )

7

2018: Hexbin plot, plotting life expectancy against generosity. The color of bins indicates the aver

餅圖

data[data['Year'] == 2018]
  .groupby( ['Continent'])['Gapminder Population'] 
  .sum() 
  .plot( 
    kind='pie', 
    figsize=(12,8), 
    cmap="Blues_r", # defaults to orangish 
  )

8

2018: Pie chart showing the total population by continent

堆積面積圖

data.groupby( ['Year','Continent'])['Gapminder Population']
 .sum()
 .unstack()
 .plot( 
    kind='area', 
    figsize=(12,8), 
    cmap="Blues", # defaults to orangish
 )

9

Population numbers accross the globe are on the rise.

折線圖

data[ data['Country name'] == 'Germany']
 .set_index('Year')['Life Ladder']
 .plot( kind='line', figsize=(12,8) )

10

Line chart depicting the development of happiness in Germany.

關於Pandas繪圖的結論

用Pandas繪圖很方便。 它易於訪問,而且速度很快。 Plot很難看。 偏離默認值是不可能的,這是可以的,因爲我們還有其他工具可以使圖表更具美學吸引力。 去看看seaborn吧。


漂亮:Seaborn的高級繪圖

Seaborn使用繪圖默認值。 爲了確保您的結果與我的匹配,請運行以下命令。

sns.reset_defaults() 
sns.set(
 rc={'figure.figsize':(7,5)},
 style="white" # nicer layout )

繪製單變量分佈

如前所述,我非常喜歡分佈。 直方圖和核密度分佈都是可視化特定變量的關鍵特徵的有效方法。 讓我們看看如何在一個圖表中爲單個變量或多個變量分配生成分佈。

11

Left chart: Histogram and kernel density estimation of “Life Ladder” for Asian countries in 2018; Ri

繪製雙變量分佈

每當我想直觀地探索兩個或多個變量之間的關係時,通常都會歸結爲某種形式的散點圖和分佈評估。 概念上相似的圖有三種變體。 在每個圖中,中心圖(散點圖,雙變量KDE和hexbin)有助於理解兩個變量之間的聯合頻率分佈。 此外,在中心圖的右邊界和上邊界,描繪了各個變量的邊際單變量分佈(作爲KDE或直方圖)。

sns.jointplot(
 x='Log GDP per capita',
 y='Life Ladder',
 data=data,
 kind='scatter' # or 'kde' or 'hex' )

12

Seaborn jointplot with scatter, bivariate kde, and hexbin in the center graph and marginal distribut

散點圖

散點圖是一種可視化兩個變量的聯合密度分佈的方法。 我們可以通過添加色相來添加第三個變量,並通過添加size參數來可視化第四個變量。

sns.scatterplot(
 x='Log GDP per capita',
 y='Life Ladder',
 data=data[data['Year'] == 2018],
 hue='Continent',
 size='Gapminder Population' ) 

# both, hue and size are optional
sns.despine() # prettier layout

13

Log GDP per capita against Life Ladder, colors based on the continent and size on population

小提琴圖

小提琴圖是箱形圖和籽粒密度估計值的組合。 它起着箱形圖的作用。 它顯示了跨類別變量的定量數據分佈,以便可以比較那些分佈。

sns.set(
 rc={'figure.figsize':(18,6)},
 style="white" ) 
sns.violinplot(
 x='Continent',
 y='Life Ladder',
 hue='Mean Log GDP per capita',
 data=data
 ) 
sns.despine()

14

Violin plot where we plot continents against Life Ladder, we use the Mean Log GDP per capita to grou

配對圖

Seaborn對圖在一個大網格中繪製了兩個變量散點圖的所有組合。 我通常感覺這有點信息過載,但是它可以幫助發現模式。

sns.set(
 style="white",
 palette="muted",
 color_codes=True
 ) 
sns.pairplot(
 data[data.Year == 2018][[ 'Life Ladder','Log GDP per capita', 'Social support','Healthy life expectancy at birth', 'Freedom to make life choices','Generosity', 'Perceptions of corruption', 'Positive affect', 'Negative affect','Confidence in national government', 'Mean Log GDP per capita' ]].dropna(),
 hue='Mean Log GDP per capita'
 )

15

Seaborn scatterplot grid where all selected variables a scattered against every other variable in th

FacetGrid

對我而言,Seaborn的FacetGrid是使用Seaborn的最令人信服的論點之一,因爲它使創建多圖變得輕而易舉。 通過對圖,我們已經看到了FacetGrid的示例。 FacetGrid允許創建按變量分段的多個圖表。 例如,行可以是一個變量(人均GDP類別),列可以是另一個變量(大陸)。

它確實比我個人需要更多的自定義(即使用matplotlib),但這仍然很吸引人。

FacetGrid —折線圖

g = sns.FacetGrid(
 data.groupby(['Mean Log GDP per capita','Year','Continent'])['Life Ladder'].mean().reset_index(),
 row='Mean Log GDP per capita',
 col='Continent',
 margin_titles=True ) 
g = (g.map(plt.plot, 'Year','Life Ladder'))

16

Life Ladder on the Y-axis, Year on the X-axis. The grid’s columns are the continent, and the grid’s rows are the different levels of Mean Log GDP per capita. Overall things seem to be getting better for the countries with a Low Mean Log GDP per Capita in North America and the countries with a Medium or High Mean Log GDP per Capita in Europe

FacetGrid —直方圖

g = sns.FacetGrid(data, col="Continent", col_wrap=3,height=4) 
g = (g.map(plt.hist, "Life Ladder",bins=np.arange(2,9,0.5)))

17

FacetGrid with a histogram of LifeLadder by continent

FacetGrid —帶註釋的KDE圖

也可以向網格中的每個圖表添加構面特定的符號。 在下面的示例中,我們添加平均值和標準偏差,並在該平均值處繪製一條垂直線(下面的代碼)。

18

Life Ladder kernel density estimation based on the continent, annotated with a mean and standard deviation

def vertical_mean_line(x, **kwargs):
    plt.axvline(x.mean(), linestyle ="--", 
                color = kwargs.get("color", "r"))
    txkw = dict(size=15, color = kwargs.get("color", "r"))

    label_x_pos_adjustment = 0.08 # this needs customization based on your data
    label_y_pos_adjustment = 5 # this needs customization based on your data
    if x.mean() < 6: # this needs customization based on your data
        tx = "mean: {:.2f}\n(std: {:.2f})".format(x.mean(),x.std())
        plt.text(x.mean() + label_x_pos_adjustment, label_y_pos_adjustment, tx, **txkw)
    else:
        tx = "mean: {:.2f}\n  (std: {:.2f})".format(x.mean(),x.std())
        plt.text(x.mean() -1.4, label_y_pos_adjustment, tx, **txkw)

_ = data.groupby(['Continent','Year'])['Life Ladder'].mean().reset_index()

g = sns.FacetGrid(_, col="Continent", height=4, aspect=0.9, col_wrap=3, margin_titles=True)
g.map(sns.kdeplot, "Life Ladder", shade=True, color='royalblue')
g.map(vertical_mean_line, "Life Ladder")

FacetGrid —熱圖

我最喜歡的繪圖類型之一是熱圖FacetGrid,即網格每個面中的熱圖。 這種類型的繪圖對於在一個繪圖中可視化四個維度和一個度量很有用。 該代碼有點麻煩,但可以根據需要快速進行調整。 值得注意的是,這種圖表需要相對大量的數據或適當的細分,因爲它不能很好地處理缺失值。

19

Facet heatmap, visualizing on the outer rows a year range, outer columns the GDP per Capita, on the inner rows the level of perceived corruption and the inner columns the continents. We see that happiness increases towards the top right (i.e., high GDP per Capita and low perceived corruption). The effect of time is not definite, and some continents (Europe and North America) seem to be happier than others (Africa).

def draw_heatmap(data,inner_row, inner_col, outer_row, outer_col, values, vmin,vmax):
    sns.set(font_scale=1)
    fg = sns.FacetGrid(
        data, 
        row=outer_row,
        col=outer_col, 
        margin_titles=True
    )

    position = left, bottom, width, height = 1.4, .2, .1, .6
    cbar_ax = fg.fig.add_axes(position) 

    fg.map_dataframe(
        draw_heatmap_facet, 
        x_col=inner_col,
        y_col=inner_row, 
        values=values, 
        cbar_ax=cbar_ax,
        vmin=vmin, 
        vmax=vmax
    )

    fg.fig.subplots_adjust(right=1.3)  
    plt.show()

def draw_heatmap_facet(*args, **kwargs):
    data = kwargs.pop('data')
    x_col = kwargs.pop('x_col')
    y_col = kwargs.pop('y_col')
    values = kwargs.pop('values')
    d = data.pivot(index=y_col, columns=x_col, values=values)
    annot = round(d,4).values
    cmap = sns.color_palette("Blues",30) + sns.color_palette("Blues",30)[0::2]
    #cmap = sns.color_palette("Blues",30)
    sns.heatmap(
        d, 
        **kwargs,
        annot=annot, 
        center=0, 
        cmap=cmap, 
        linewidth=.5
    )

# Data preparation
_ = data.copy()
_['Year'] = pd.cut(_['Year'],bins=[2006,2008,2012,2018])

_['GDP per Capita'] = _.groupby(['Continent','Year'])['Log GDP per capita'].transform(
    pd.qcut,
    q=3,
    labels=(['Low','Medium','High'])
).fillna('Low')

_['Corruption'] = _.groupby(['Continent','GDP per Capita'])['Perceptions of corruption'].transform(
    pd.qcut,
    q=3,
    labels=(['Low','Medium','High'])
)

_ = _[_['Continent'] != 'Oceania'].groupby(['Year','Continent','GDP per Capita','Corruption'])['Life Ladder'].mean().reset_index()
_['Life Ladder'] = _['Life Ladder'].fillna(-10)

draw_heatmap(
    data=_,
    outer_row='Corruption',
    outer_col='GDP per Capita',
    inner_row='Year',
    inner_col='Continent',
    values='Life Ladder',
    vmin=3,
    vmax=8,
)

很棒:使用plotly創建出色的交互式圖

最後,不再需要Matplotlib! Plotly具有三個重要功能:

· 懸停:將鼠標懸停在圖表上時,將彈出註釋

· 交互性:無需任何其他設置即可使圖表互動(例如,穿越時空的旅程)

· 漂亮的地理空間圖:Plotly具有一些內置的基本地圖繪製功能,但是另外,可以使用mapbox集成來生成驚人的圖表。

點圖

我們通過運行fig = x。(PARAMS)然後調用fig.show()來調用繪圖:

fig = px.scatter(
    data_frame=data[data['Year'] == 2018], 
    x="Log GDP per capita", 
    y="Life Ladder", 
    size="Gapminder Population", 
    color="Continent",
    hover_name="Country name",
    size_max=60
)
fig.show()

20

Plotly scatter plot, plotting Log GDP per capita against Life Ladder, where color indicates continent and size of the marker the population

散點圖-漫步時光

fig = px.scatter(
    data_frame=data, 
    x="Log GDP per capita", 
    y="Life Ladder", 
    animation_frame="Year", 
    animation_group="Country name",
    size="Gapminder Population", 
    color="Continent", 
    hover_name="Country name", 
    facet_col="Continent",
    size_max=45,
    category_orders={'Year':list(range(2007,2019))}     
)
fig.show()

在這裏插入圖片描述

Visualization of how the plotted data changes over the years

並行類別-一種可視化類別的有趣方式

def q_bin_in_3(col):
    return pd.qcut(
        col,
        q=3,
        labels=['Low','Medium','High']
    )
_ = data.copy()
_['Social support'] = _.groupby('Year')['Social support'].transform(q_bin_in_3)
_['Life Expectancy'] = _.groupby('Year')['Healthy life expectancy at birth'].transform(q_bin_in_3)
_['Generosity'] = _.groupby('Year')['Generosity'].transform(q_bin_in_3)
_['Perceptions of corruption'] = _.groupby('Year')['Perceptions of corruption'].transform(q_bin_in_3)
_ = _.groupby(['Social support','Life Expectancy','Generosity','Perceptions of corruption'])['Life Ladder'].mean().reset_index()
fig = px.parallel_categories(_, color="Life Ladder", color_continuous_scale=px.colors.sequential.Inferno)
fig.show()

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TjEZPOpw-1589858385326)(https://raw.githubusercontent.com/Thobian/typora-image/master/demo/202005/19/095155-183124.gif)]

Seems like not all countries with high life expectations are happy!

條形圖—交互式過濾器的示例

fig = px.bar(
    data, 
    x="Continent", 
    y="Gapminder Population", 
    color="Mean Log GDP per capita", 
    barmode="stack", 
    facet_col="Year",
    category_orders={"Year": range(2007,2019)},
    hover_name='Country name',
    hover_data=[
        "Mean Log GDP per capita",
        "Gapminder Population",
        "Life Ladder"
    ]
)
fig.show()

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qeImKgBs-1589858385327)(https://raw.githubusercontent.com/Thobian/typora-image/master/demo/202005/19/100115-647988.gif)]

Filtering a bar chart is easy. Not surprisingly, South Korea is among the wealthy countries in Asia.

Choropleth plot-幸福如何隨着時間而變化

fig = px.choropleth(
    data, 
    locations="ISO3", 
    color="Life Ladder", 
    hover_name="Country name", 
    animation_frame="Year")
fig.show()

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-IkIyGUSu-1589858385329)(https://raw.githubusercontent.com/Thobian/typora-image/master/demo/202005/19/100958-294513.gif)]

Map visualization of how happiness evolves over the years. Syria and Afghanistan are at the very end of the Life Ladder range (unsurprisingly)

結束語

在本文中,我們學習瞭如何成爲真正的Python可視化高手,瞭解瞭如何在快速探索方面提高效率,以及在再次召開董事會會議時如何創建更精美的圖表。 還有交互式地圖,這在繪製地理空間數據時特別有用哦。

本文翻譯自Fabian Bosler的文章《Learn how to create beautiful and insightful charts with Python — the Quick, the Pretty, and the Awesome》 參考https://towardsdatascience.com/plotting-with-python-c2561b8c0f1f)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章