6個頂級Python可視化庫
文章:蘿卜大雜燴
當可視化一個DataFrame時,選擇使用哪個可視化庫確實是一個頭疼的事情。
這篇文章云朵君將和大家一起學習每個庫的優(yōu)點和缺點。到最后,對它們的不同特點有更好的了解,在合適的時候更容易選擇合適的庫。
將通過專注于幾個具體的屬性來評價一個可視化工具的優(yōu)缺點:
互動性
你想要交互式可視化嗎?像Altair、Bokeh和Plotly這樣的庫允許你創(chuàng)建交互式圖表,用戶可以探索和互動。
另外,一些庫(如Matplotlib)將可視化渲染成靜態(tài)圖像,使其適合在論文、幻燈片或演示中解釋概念。
語法和靈活性
不同庫的語法有什么不同?低級別的庫,如Matplotlib,提供了廣泛的靈活性,可以完成幾乎任何事情。然而,API也是很復雜的。
像Altair這樣的聲明式庫簡化了數(shù)據(jù)到可視化的映射,提供了一個更直觀的語法。
數(shù)據(jù)類型和視覺化
是否在處理專門的用例,如地理圖或大數(shù)據(jù)集?考慮一個特定的庫是否支持繪圖類型或有效處理大型數(shù)據(jù)集。
數(shù)據(jù)
import pandas as pd
# 強烈推薦關注@公眾號:數(shù)據(jù)STUDIO,更多優(yōu)質(zhì)內(nèi)容等你~
new_profile = pd.read_csv('https://gist.githubusercontent.com/khuyentran1401/98658198f0ef0cb12abb34b4f2361fd8/raw/ece16eb32e1b41f5f20c894fb72a4c198e86a5ea/github_users.csv')
new_profile
Matplotlib
Matplotlib[1]可能是最常見的用于可視化數(shù)據(jù)的Python庫。幾乎所有對數(shù)據(jù)科學感興趣的人都可能至少使用過一次Matplotlib。
優(yōu)點
易于解釋的數(shù)據(jù)屬性
在分析數(shù)據(jù)時,快速了解數(shù)據(jù)分布情況往往非常有用的。
例如,如果你想檢查擁有最多粉絲的前100名用戶的分布情況,通常Matplotlib就足夠了。
import matplotlib.pyplot as plt
top_followers = new_profile.sort_values(by="followers", axis=0, ascending=False)[:100]
fig = plt.figure()
plt.bar(top_followers.user_name, top_followers.followers)
plt.show()
盡管Matplotlib的X軸表示方法并不理想,但該圖可以讓人清楚地了解數(shù)據(jù)的分布。
多樣性
Matplotlib的功能非常全面,能夠生成各種類型的圖形。Matplotlib的網(wǎng)站[2]提供了全面的文檔和各種圖形的圖庫,使得它很容易找到幾乎任何類型的繪圖的教程。
fig = plt.figure()
plt.text(
0.6,
0.7,
"learning",
size=40,
rotation=20.0,
ha="center",
va="center",
bbox=dict(
boxstyle="round",
ec=(1.0, 0.5, 0.5),
fc=(1.0, 0.8, 0.8),
),
)
plt.text(
0.55,
0.6,
"machine",
size=40,
rotation=-25.0,
ha="right",
va="top",
bbox=dict(
boxstyle="square",
ec=(1.0, 0.5, 0.5),
fc=(1.0, 0.8, 0.8),
),
)
plt.show()
缺點
雖然Matplotlib幾乎可以繪制任何東西,但生成非基本的圖或為審美目的調(diào)整圖可能很復雜。
如果你打算向他人展示你的數(shù)據(jù),定制X軸、Y軸和其他繪圖元素可能需要大量的努力。這是由于Matplotlib的低級接口造成的。
num_features = new_profile.select_dtypes("int64")
correlation = num_features.corr()
fig, ax = plt.subplots()
im = plt.imshow(correlation)
ax.set_xticklabels(correlation.columns)
ax.set_yticklabels(correlation.columns)
plt.setp(ax.get_xticklabels(),
rotation=45,
ha="right",
rotation_mode="anchor")
plt.show()
經(jīng)驗之談:Matplotlib 能夠制作任何繪圖,但與其他庫相比,創(chuàng)建復雜的繪圖往往需要更多的代碼。
Seaborn
Seaborn[3]是一個建立在Matplotlib之上的Python數(shù)據(jù)可視化庫。它提供了一個更高層次的界面,簡化了創(chuàng)建具有視覺吸引力的圖的過程。
優(yōu)點
減少的代碼
Seaborn提供了一個更高層次的接口來生成與Matplotlib類似的圖。這意味著你可以用更少的代碼和更漂亮的視覺設計來實現(xiàn)類似的可視化。
例如,使用與之前相同的數(shù)據(jù),我們可以創(chuàng)建一個熱圖,而無需明確設置x和y標簽:
correlation = new_profile.corr()
sns.heatmap(correlation, annot=True)
這使得熱圖在視覺上更有吸引力,而不需要額外的配置。
改善普通圖表的美感
Seaborn是常見繪圖類型的熱門選擇,如柱狀圖、箱形圖、計數(shù)圖和直方圖。Seaborn不僅需要較少的代碼來生成這些圖,而且它們還具有增強的視覺美感。
在下面的例子中,由于Seaborn的默認設置,計數(shù)圖在視覺上顯得更加吸引人:
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
ax = sns.countplot(x="class", data=titanic)
缺點
Seaborn盡管有其優(yōu)勢,但并不像Matplotlib那樣擁有廣泛的繪圖類型集合。雖然它在流行的繪圖類型方面表現(xiàn)出色,但對于更專業(yè)或定制的繪圖,它可能無法提供同樣廣泛的選項。
經(jīng)驗之談:Seaborn 是Matplotlib的一個高級版本。盡管它沒有像Matplotlib那樣廣泛的集合,但Seaborn可以用更少的代碼使流行的繪圖,如柱狀圖、盒狀圖、熱圖等看起來更漂亮。
Plotly
Plotly[4]圖形庫提供了一種毫不費力的方式來創(chuàng)建交互式和高質(zhì)量的圖形。它提供了一系列類似于Matplotlib和Seaborn的圖表類型,包括線圖、散點圖、面積圖、條形圖等等。
優(yōu)點
與R相似
如果你熟悉在R中創(chuàng)建繪圖,并在使用Python時懷念它的功能,Plotly是一個很好的選擇。它允許你用Python實現(xiàn)同樣水平的高質(zhì)量繪圖。
Plotly Express尤其突出,因為它只用一行Python代碼就能創(chuàng)建令人印象深刻的圖表。比如說:
import plotly.express as px
# 強烈推薦關注@公眾號:數(shù)據(jù)STUDIO,更多優(yōu)質(zhì)內(nèi)容等你~
fig = px.scatter(
new_profile[:100],
x="followers",
y="total_stars",
color="forks",
size="contribution",
)
fig.show()
交互式圖表創(chuàng)建
Plotly擅長創(chuàng)建交互式圖表,這不僅增強了視覺吸引力,而且使觀眾能夠更詳細地探索數(shù)據(jù)。
讓我們考慮一下前面的用Matplotlib創(chuàng)建的條形圖例子。下面是如何用Plotly實現(xiàn)的:
top_followers = new_profile.sort_values(by="followers", axis=0, ascending=False)[:100]
fig = px.bar(
top_followers,
x="user_name",
y="followers",
)
fig.show()
通過類似的代碼,Plotly可以生成一個交互式的圖表,用戶可以將鼠標懸停在每個條形圖上,查看相應的用戶和關注者數(shù)量。這種互動性使你的可視化的消費者有能力自己去探索數(shù)據(jù)。
復雜地塊中的簡單性
Plotly簡化了復雜圖的創(chuàng)建,這在其他庫中可能是個挑戰(zhàn)。
例如,如果我們想在地圖上可視化GitHub用戶的位置,我們可以獲得他們的經(jīng)緯度,并據(jù)此繪制:
location_df = pd.read_csv(
"https://gist.githubusercontent.com/khuyentran1401/ce61bbad3bc636bf2548d70d197a0e3f/raw/ab1b1a832c6f3e01590a16231ba25ca5a3d761f3/location_df.csv",
index_col=0,
)
m = px.scatter_geo(
location_df,
lat="latitude",
lon="longitude",
color="total_stars",
size="forks",
hover_data=["user_name", "followers"],
title="Locations of Top Users",
)
m.show()
只需幾行代碼,Plotly就能在地圖上漂亮地表示用戶的位置。氣泡的顏色代表分叉的數(shù)量,而大小則與星星的總數(shù)相對應。
經(jīng)驗之談:Plotly 是一個很好的選擇,可以用最少的代碼來創(chuàng)建交互式和出版質(zhì)量的圖表。它提供了廣泛的可視化功能,并簡化了創(chuàng)建復雜圖表的過程。
Altair
Altair[5]是一個強大的Python聲明式統(tǒng)計可視化庫,基于Vega-Lite。它在創(chuàng)建需要大量統(tǒng)計轉(zhuǎn)換的圖表時大放異彩。
優(yōu)點
簡單的可視化語法
Altair利用直觀的語法來創(chuàng)建可視化。你只需要指定數(shù)據(jù)列和編碼通道之間的聯(lián)系,其余的繪圖工作都是自動處理的。這種簡單性使得信息的可視化變得快速而直觀。
例如,使用泰坦尼克號的數(shù)據(jù)集來計算每個班級的人數(shù):
import seaborn as sns
import altair as alt
titanic = sns.load_dataset("titanic")
alt.Chart(titanic).mark_bar().encode(alt.X("class"), y="count()")
Altair簡潔的語法允許你專注于數(shù)據(jù)和它的關系,從而產(chǎn)生高效和富有表現(xiàn)力的可視化。
易于數(shù)據(jù)轉(zhuǎn)換
Altair使其在創(chuàng)建圖表時毫不費力地進行數(shù)據(jù)轉(zhuǎn)換。
例如,如果你想在泰坦尼克號數(shù)據(jù)集中找到每個性別的平均年齡,你可以在代碼本身中進行轉(zhuǎn)換:
hireable = (
alt.Chart(titanic)
.mark_bar()
.encode(x="sex:N", y="mean_age:Q")
.transform_aggregate(mean_age="mean(age)", groupby=["sex"])
)
hireable
Altair的transform_aggregate()函數(shù)使你能夠在飛行中匯總數(shù)據(jù),并在你的可視化中使用這些結(jié)果。
你也可以使用:N 或:Q符號指定數(shù)據(jù)類型,如名義(沒有任何順序的分類數(shù)據(jù))或定量(數(shù)值的衡量)。
查看數(shù)據(jù)轉(zhuǎn)換的完整列表[6]。
鏈接圖表
Altair提供了令人印象深刻的將多個地塊連接在一起的能力。你可以根據(jù)用戶的互動,使用選擇來過濾所附圖塊的內(nèi)容。
例如,在散點圖上直觀地顯示所選區(qū)間內(nèi)每個階層的人數(shù):
brush = alt.selection(type="interval")
points = (
alt.Chart(titanic)
.mark_point()
.encode(
x="age:Q",
y="fare:Q",
color=alt.condition(brush, "class:N", alt.value("lightgray")),
)
.add_selection(brush)
)
bars = (
alt.Chart(titanic)
.mark_bar()
.encode(y="class:N", color="class:N", x="count(class):Q")
.transform_filter(brush)
)
points & bars
當你在散點圖中選擇一個區(qū)間時,柱狀圖會動態(tài)更新以反映過濾后的數(shù)據(jù)。Altair連接圖的能力允許高度互動的可視化和即時計算,不需要運行Python服務器。
缺點
Altair的簡單圖表,如柱狀圖,可能看起來不像Seaborn或Plotly等庫中的圖表那樣有風格,除非你指定自定義風格。
Altair建議在處理超過5000個樣本的數(shù)據(jù)集時,在可視化之前對數(shù)據(jù)進行匯總。處理更大的數(shù)據(jù)集可能需要額外的步驟來管理數(shù)據(jù)大小和復雜性。
經(jīng)驗之談:Altair 是創(chuàng)建復雜統(tǒng)計圖表的絕佳選擇。雖然它可能缺乏一些默認的樣式選項,并且在處理大型數(shù)據(jù)集時有局限性,但Altair的簡單性、數(shù)據(jù)轉(zhuǎn)換能力和鏈接圖使其成為統(tǒng)計可視化的強大工具。
Bokeh
Bokeh是一個高度靈活的交互式可視化庫,專為網(wǎng)絡瀏覽器設計。
優(yōu)點
Matplotlib的交互式版本
在交互式可視化方面,Bokeh作為與Matplotlib最相似的庫脫穎而出。Matplotlib是一個低級別的可視化庫,而Bokeh同時提供了高級和低級別的接口。使用Bokeh,你可以創(chuàng)建類似于Matplotlib的復雜圖,但代碼行數(shù)更少,分辨率更高。
例如,Matplotlib的圓形圖...
import matplotlib.pyplot as plt
# 強烈推薦關注@公眾號:數(shù)據(jù)STUDIO,更多優(yōu)質(zhì)內(nèi)容等你~
fig, ax = plt.subplots()
x = [1, 2, 3, 4, 5]
y = [2, 5, 8, 2, 7]
for x, y in zip(x, y):
ax.add_patch(
plt.Circle((x, y), 0.5, edgecolor="#f03b20", facecolor="#9ebcda", alpha=0.8)
)
# Use adjustable='box-forced' to make the plot area square-shaped as well.
ax.set_aspect("equal", adjustable="datalim")
ax.set_xbound(3, 4)
ax.plot() # Causes an autoscale update.
plt.show()
......可以通過使用虛化技術實現(xiàn)更好的分辨率和更大的效用:
from bokeh.io import show, output_notebook
from bokeh.models import Circle
from bokeh.plotting import figure
output_notebook()
plot = figure(tools="tap", title="Select a circle")
renderer = plot.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=50)
selected_circle = Circle(fill_alpha=1, fill_color="firebrick", line_color=None)
nonselected_circle = Circle(fill_alpha=0.2, fill_color="blue", line_color="firebrick")
renderer.selection_glyph = selected_circle
renderer.nonselection_glyph = nonselected_circle
show(plot)
圖表之間的聯(lián)系
Bokeh使建立地塊之間的聯(lián)系變得非常容易。應用于一個圖的變化可以自動反映在另一個具有類似變量的圖中。這個功能允許探索多個地塊之間的關系。
例如,如果你創(chuàng)建了三個并排的圖形,并想觀察它們的關系,你可以利用鏈接刷:
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource
source = ColumnDataSource(new_profile)
TOOLS = "box_select,lasso_select,help"
TOOLTIPS = [
("user", "@user_name"),
("followers", "@followers"),
("following", "@following"),
("forks", "@forks"),
("contribution", "@contribution"),
]
s1 = figure(tooltips=TOOLTIPS, title=None, tools=TOOLS)
s1.circle(x="followers", y="following", source=source)
s2 = figure(tooltips=TOOLTIPS, title=None, tools=TOOLS)
s2.circle(x="followers", y="forks", source=source)
s3 = figure(tooltips=TOOLTIPS, title=None, tools=TOOLS)
s3.circle(x="followers", y="contribution", source=source)
p = gridplot([[s1, s2, s3]])
show(p)
通過利用ColumnDataSource,數(shù)據(jù)可以在繪圖之間共享。因此,當一個情節(jié)發(fā)生變化時,其他情節(jié)也會相應地自動更新。
缺點
作為一個具有某種中間層次界面的庫,Bokeh通常需要更多的代碼來產(chǎn)生與Seaborn、Altair或Plotly相同的圖。雖然Bokeh需要的代碼比Matplotlib少,但與其他庫相比,它可能需要額外的代碼行來實現(xiàn)類似的質(zhì)量輸出。
例如,使用泰坦尼克號數(shù)據(jù)創(chuàng)建同樣的計數(shù)圖,除了需要提前轉(zhuǎn)換數(shù)據(jù)外,如果我們想讓圖表看起來漂亮,還需要設置條形圖的寬度和顏色。
如果我們不為條形圖增加寬度,圖表會是這樣的:
from bokeh.transform import factor_cmap
from bokeh.palettes import Spectral6
titanic_groupby = titanic.groupby("class")["survived"].sum().reset_index()
p = figure(x_range=list(titanic_groupby["class"]))
p.vbar(
x="class",
top="survived",
source=titanic_groupby,
fill_color=factor_cmap(
"class", palette=Spectral6, factors=list(titanic_groupby["class"])
),
)
show(p)
from bokeh.transform import factor_cmap
from bokeh.palettes import Spectral6
titanic_groupby = titanic.groupby("class")["survived"].sum().reset_index()
p = figure(x_range=list(titanic_groupby["class"]))
p.vbar(
x="class",
top="survived",
source=titanic_groupby,
fill_color=factor_cmap(
"class", palette=Spectral6, factors=list(titanic_groupby["class"])
),
)
show(p)
因此,我們需要手動調(diào)整尺寸以使繪圖更美觀:
p = figure(x_range=list(titanic_groupby["class"]))
p.vbar(
x="class",
top="survived",
width=0.9,
source=titanic_groupby,
fill_color=factor_cmap(
"class", palette=Spectral6, factors=list(titanic_groupby["class"])
),
)
show(p)
經(jīng)驗之談:Bokeh 的獨特優(yōu)勢在于它能夠提供一系列的界面,從低到高,從而能夠創(chuàng)建多功能的、具有視覺吸引力的圖形。然而,與其他庫相比,在追求類似的情節(jié)質(zhì)量時,這種靈活性往往導致需要更多的代碼。
Folium
Folium[7]簡化了在交互式小冊子地圖上實現(xiàn)數(shù)據(jù)可視化的過程。這個庫提供了來自OpenStreetMap、Mapbox和Stamen的內(nèi)置瓦片集。
優(yōu)點
易于創(chuàng)建一個帶有標記的地圖
與Plotly、Altair和Bokeh等其他選項相比,F(xiàn)olium通過利用開放的街道地圖提供了一種更直接的方法。這給人一種類似于谷歌地圖的體驗,而且代碼最少。
還記得我們用Plotly創(chuàng)建的可視化Github用戶位置的地圖嗎?有了Folium,我們可以進一步增強地圖的外觀。
import folium
# 在一個列表中保存緯度、經(jīng)度和地點的名稱*
lats = location_df["緯度"]
lons = location_df["經(jīng)度"]
names = location_df["location"]
# 用一個初始位置創(chuàng)建一個地圖*
m = folium.Map(location=[lats[0], lons[0]] )
for lat, lon, name in zip(lats, lons, names):
# 用其他位置創(chuàng)建標記*
folium.Marker(
location=[lat, lon], popup=name, icon=folium.Icon(color="green")
).add_to(m)
m
只用幾行代碼,我們就創(chuàng)建了一個顯示用戶位置的真實地圖。
添加地點
Folium通過允許加入標記,可以很容易地添加其他用戶的潛在位置。
# 啟用在地圖中添加更多的位置
m = m.add_child(folium.ClickForMarker(popup="Potential Location"))
在地圖上點擊,就在你點擊的地方生成一個新的位置標記。
插件
Folium提供各種插件,可以與你的地圖一起利用,包括Altair的插件。例如,如果我們想將全球Github用戶的總星數(shù)熱圖可視化,并識別出擁有大量頂級用戶和星數(shù)的地區(qū),F(xiàn)olium熱圖插件就可以實現(xiàn)這一目的。
# heatmap
# 強烈推薦關注@公眾號:數(shù)據(jù)STUDIO,更多優(yōu)質(zhì)內(nèi)容等你~
from folium.plugins import HeatMap
m = folium.Map(location=[lats[0], lons[0]])
HeatMap(data=location_df[["latitude", "longitude", "total_stars"]]).add_to(m)
m
經(jīng)驗之談:Folium 只需幾行代碼就能創(chuàng)建互動地圖。它提供了類似于谷歌地圖的用戶體驗。
參考資料
Matplotlib: https://matplotlib.org/
[2]網(wǎng)站: https://matplotlib.org/tutorials/introductory/sample_plots.html
[3]Seaborn: https://seaborn.pydata.org/
[4]Plotly: https://plotly.com/python/
[5]Altair: https://altair-viz.github.io/
[6]完整列表: https://altair-viz.github.io/user_guide/transform/index.html
[7]Folium: https://python-visualization.github.io/folium/
