Matplotlib是Python最重要的可视化库,但是,过于复杂,Seaborn对其主要功能做了封装,隐藏复杂参数,仅需要几行代码就可以实现优美的统计图,但功能有限:Seaborn ; 此次更新主要拓展Seaborn的核心功能 —与pandas的集成、数据和图形之间的自动映射、统计转换
— 使得Seaborn成为一个更具组合性、可扩展性和全面性的可视化库。 为了这次更新,已经开发了8个月,依旧还有很多工作要做,更新版具体发布时间待定 ,但是会在发布前发布系列alpha/beta releases,以获取测试反馈。 👇👇下面看看主要哪些方面发生了更新 👇👇
嫌长文,直接看文章末尾小结。
基本语法 导入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=xx
、jitter=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: https://seaborn.pydata.org/nextgen/ -END-