參考ggplot2,Seaborn將迎來超大版本更新!

語言: CN / TW / HK

最新消息, Seaborn將迎來API重寫級別 版本更新,本文羅列重大改變,太值得期待了!

  • Matplotlib是Python最重要的可視化庫,但是,過於複雜,Seaborn對其主要功能做了封裝,隱藏複雜參數,僅需要幾行代碼就可以實現優美的統計圖,但功能有限: Seaborn

  • 此次更新主要拓展Seaborn的核心功能 — 與pandas的集成、數據和圖形之間的自動映射、統計轉換 — 使得Seaborn成為一個更具組合性、可擴展性和全面性的可視化庫。
  • 作者直言,更新靈感不少源於R語言中 ggplot2背後的圖層圖形語法 ,去其糟粕,取其精華,做了很多優化,但是Seaborn不等於Python版ggplot2 ( plotnine );

  • 為了這次更新,已經開發了8個月,依舊還有很多工作要做, 更新版具體發佈時間待定 ,但是會在發佈前發佈系列alpha/beta releases,以獲取測試反饋。

:point_down::point_down: 下面看看主要哪些方面發生了更新 :point_down::point_down:

嫌長文,直接看文章末尾小結。

基本語法

導入Seaborn

#方法一
import seaborn.objects as so #不再是import seaborn as sns

#方法二
from seaborn.objects import *

繪圖主函數 變成了 seaborn.objects.Plot

import seaborn
tips = seaborn.load_dataset("tips") #導入內置數據

so.Plot(tips, x="total_bill", y="tip") #繪製空Figure

add在Figure上添加散點圖層,

so.Plot(tips, x="total_bill", y="tip").add(so.Scatter()) 
#.add(so.Scatter())是不是有ggplot2 + 添加圖層的影子~

全局個性化,

so.Plot(tips).add(so.Scatter(), x="total_bill", y="tip")

每個圖層個性化,

(
so.Plot(tips, x="total_bill", y="tip")
.add(so.Scatter(color=".6"))
.add(so.Scatter(), data=tips.query("size == 2"))
)
(
so.Plot(tips, x="total_bill", y="tip", color="day", fill="time")
.add(so.Scatter(fillalpha=.8))
)

核心組件1-圖層對象Mark

每個圖層都需要一個Mark對象,它定義瞭如何繪製繪圖。將對應於現有seaborn功能和提供新功能的標記,但是,很多還沒有實現,

so.Plot(tips, y="day", x="total_bill")
.add(so.Dot(color="#698", alpha=.5)) #直接設置Mark(此處為Dot)特性,而不是映射它們.

核心組件2-數據轉換Stat

在新版本中,每個層都可以接受一個數據轉換的Stat對象,

so.Plot(fmri, x="timepoint", y="signal", color="event").add(so.Line(), so.Agg(), group="subject")

自定義Mark和Stat對象

class PeakAnnotation(so.Mark):
def _plot_split(self, keys, data, ax, kws):
ix = data["y"].idxmax()
ax.annotate(
"The peak", data.loc[ix, ["x", "y"]],
xytext=(10, -100), textcoords="offset points",
va="top", ha="center",
arrowprops=dict(arrowstyle="->", color=".2"),

)

(
so.Plot(fmri, x="timepoint", y="signal")
.add(so.Line(), so.Agg())
.add(PeakAnnotation(), so.Agg())
)

核心組件3-圖形自適應the Move

新版本里,圖形的一些調整都匯聚在move對象中,取代老版本中的 dodge=xxjitter=xx、multiple= xx等設置,

(
so.Plot(tips, "day", "total_bill", color="time", alpha="sex")
.add(so.Bar(), so.Agg(), move=so.Dodge())
)
(
so.Plot(tips, "day", "total_bill", color="time", alpha="smoker")
.add(so.Dot(), move=[so.Dodge(by=["color"]), so.Jitter(.5)])
)

個性化設置

新版本將添加更多圖形個性化設置功能,

(
so.Plot(planets, x="mass", y="distance", color="year")
.map_color("flare", norm=(2000, 2010))
.scale_numeric("x", "log")
.add(so.Scatter(pointsize=3))
)
#以上設置順序不分先後
(
so.Plot(planets, y="year", x="orbital_period")
.scale_numeric("x", "log")
.add(so.Scatter(alpha=.5, marker="x"), color="method")
.add(so.Line(linewidth=2, color=".2"), so.Agg(), orient="h")
)

子圖定義

新版本中分面Facet被隱式地內置,

(
so.Plot(tips, x="total_bill", y="tip")
.facet("time", order=["Dinner", "Lunch"])
.add(so.Scatter())
)

注意區別於老版本的FacetGrid,

(
so.Plot(tips, x="total_bill", y="tip", col="day")
.add(so.Scatter(color=".75"), col=None)
.add(so.Scatter(), color="day")
.configure(figsize=(7, 3))
)

新版本依舊包含 PairGrid功能,

(
so.Plot(tips, y="day")
.pair(x=["total_bill", "tip"])
.add(so.Dot())
)

FacetGrid和 PairGrid可聯合使用,

(
so.Plot(tips, x="day")
.facet("sex")
.pair(y=["total_bill", "tip"])
.add(so.Dot())
)

faceted和paired圖均可沿着列和行“ wrapped ”,

class Histogram(so.Mark):  # TODO replace once we implement
def _plot_split(self, keys, data, ax, kws):
ax.hist(data["x"], bins="auto", **kws)
ax.set_ylabel("count")

(
so.Plot(tips)
.pair(x=tips.columns, wrap=3)
.configure(sharey=False)
.add(Histogram())
)

總之,新版本中,“axes-level” 和“figure-level” 無差異。

圖形迭代、渲染

迭代:可定義一個基礎圖形,然後按需求在基礎圖形上繪製不同圖形,不同圖形之間相互獨立,

#定義基礎圖形p
p = (
so.Plot(fmri, x="timepoint", y="signal", color="event")
.map_color(palette="crest")
)

p.add(so.Line()) #繪製折線圖
p.add(so.Line(), group="subject")

與Matplotlib集成

“axes-level”容易實現,可直接對子圖操作,

import matplotlib as mpl
_, ax = mpl.figure.Figure(constrained_layout=True).subplots(1, 2)
(
so.Plot(tips, x="total_bill", y="tip")
.on(ax)
.add(so.Scatter())
)

“figure-level”  比較難纏,

f = mpl.figure.Figure(constrained_layout=True)
(
so.Plot(tips, x="total_bill", y="tip")
.on(f)
.add(so.Scatter())
.facet("time")
)

subfigures讓多子圖更簡單,

sf1, sf2 = f.subfigures(1, 2)
(
so.Plot(tips, x="total_bill", y="tip", color="day")
.add(so.Scatter())
.on(sf1)
.plot()
)
(
so.Plot(tips, x="total_bill", y="tip", color="day")
.facet("day", wrap=2)
.add(so.Scatter())
.on(sf2)
.plot()
)

小結

  • 如果該新版本發佈, Seaborn老版本子圖難實現、個性化難、需要重度依賴Matplotlib的缺陷基本被修復
  • 新版本吸收了ggplot2的部分屬性,對R用户比較容易上手;

  • 但是, Seaborn支持圖形類別有限 的問題沒有看到修復;
  • 再者,到底啥時候新版本能夠發佈, This is very much a work in progress

  • 總之,非常值得期待。

  • ref: http://seaborn.pydata.org/nextgen/

近期文章

視頻專欄課 | Python網絡爬蟲與文本分析

如何在DataFrame中使用If-Else條件語句創建新列

BERTopic 主題建模庫 | 建議收藏

Top2Vec | 主題建模和語義搜索庫

案例實戰 | 企業信息數據採集

使用文本相似度可以識別變化的時間點

PNAS | 文本網絡分析&文化橋樑Python代碼實現

tomotopy | 速度最快的LDA主題模型

dvt | 視覺文化分析的Python工具包

Stargazer庫 | 創建漂亮可發表的多元迴歸表

人文社科類Python免費教程列表

量化歷史語言學-貝葉斯語言譜系分析

Python與文化分析入門

Backtrader庫 | 均線買入賣出策略實現

讀完本文你就瞭解什麼是文本分析

文本分析在經管領域中的應用概述

綜述:文本分析在市場營銷研究中的應用

文本分析方法在《管理世界》(2021.5)中的應用

hiResearch 定義自己的科研首頁

SciencePlots | 科研樣式繪圖庫

Wow~70G上市公司定期報吿數據集

漂亮~pandas可以無縫銜接Bokeh

YelpDaset: 酒店管理類數據集10+G