专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python爱好者社区  ·  DeepSeek彻底爆了。。。 ·  3 天前  
Python开发者  ·  董事长十几刀刺死 ... ·  昨天  
Python中文社区  ·  FinRL:深度强化学习驱动的量化交易框架 ·  2 天前  
小小的python学习社  ·  python 从入门到精通——完整教程 ·  2 天前  
Python开发者  ·  5 人 3 小时复刻开源版 ... ·  4 天前  
51好读  ›  专栏  ›  Python开发者

Jupyter 常见可视化框架的选择

Python开发者  · 公众号  · Python  · 2017-11-17 19:30

正文

(点击 上方公众号 ,可快速关注)


来源:三次方根

segmentfault.com/a/1190000011831228

如有好文章投稿,请点击 → 这里了解详情


对于以Python作为技术栈的数据科学工作者,Jupyter是不得不提的数据报告工具。可能对于R社区而言,鼎鼎大名的ggplot2是常见的可视化框架,而大家对于Python,以及Jupyter为核心的交互式报告的可个视化方案就并没有那么熟悉。本文试图比较几个常用的解决方案,方便大家选择。


选择标准


称述式还是命令式


数据工作者使用的图的类别,常见的就三类:GIS可视化、网络可视化和统计图。因此,大多数场景下,我们并不想接触非常底层的基于点、线、面的命令,所以,选择一个好的封装的框架相当重要。


当然,公认较好的封装是基于《The Grammar of Graphics (Statistics and Computing)》一书,R中的ggplot2基本上就是一个很好的实现。我们基本上可以像用「自然语言」(Natural Language)一样使用这些绘图命令。我们姑且采用计算机科学领域的「陈述式」来表达这种绘图方式。


相反,有时候,以下情形时,我们可能对于这种绘图命令可能并不在意:


  1. 出图相当简单,要求绘制速度,一般大的框架较重(当然只是相对而言);

  2. 想要对细节做非常详尽的微调,一般大框架在微调方面会相对复杂或者退缩成一句句命令;

  3. 是统计作图可视化的创新者,想要尝试做出新的可视化实践。


这些情况下,显然,简单操作式并提供底层绘制命令的框架更让人愉快,与上面类似,我们借用「命令式」描述这类框架。


是否交互


与传统的交付静态图标不同,基于Web端的Jupter的一大好处就是可以绘制交互的图标(最近的RNotebook也有实现),因此,是否选择交互式,也是一个需要权衡的地方。


交互图的优势:


  1. 可以提供更多的数据维度和信息;

  2. 用户端可以做更多诸如放大、选取、转存的操作;

  3. 可以交付BI工程师相应的JavaScript代码用以工程化;

  4. 效果上比较炫酷,考虑到报告接受者的特征可以选择。


非交互图的优势:


  1. 报告文件直接导出成静态文件时相对问题,不会因为转换而损失信息;

  2. 图片可以与报告分离,必要时作为其他工作的成果;

  3. 不需要在运行Notebook时花很多世界载入各类前端框架。


是非内核交互


Jupyter上大多数命令通过以下方式获取数据,而大多数绘图方式事实上只是通过Notebook内的代码在Notebook与内核交互后展示出输出结果。但ipywidgets框架则可以实现Code Cell中的代码与Notebook中的前端控件(比如按钮等)绑定来进行操作内核,提供不同的绘图结果,甚至某些绘图框架的每个元素都可以直接和内核进行交互。


用这些框架,可以搭建更复杂的Notebook的可视化应用,但缺点是因为基于内核,所以在呈递、展示报告时如果使用离线文件时,这些交互就会无效。


框架罗列


matplotlib


最家喻户晓的绘图框架是matplotlib,它提供了几乎所有python内静态绘图框架的底层命令。如果按照上面对可视化框架的分法,matplotlib属于非交互式的的「命令式」作图框架。


## matplotlib代码示例

from pylab import *

X = np . linspace ( - np . pi , np . pi , 256 , endpoint = True )

C , S = np . cos ( X ), np . sin ( X )

plot ( X , C )

plot ( X , S )

show ()


优点是相对较快,底层操作较多。缺点是语言繁琐,内置默认风格不够美观。


matplotlib在jupyter中需要一些配置,可以展现更好的效果,详情参见这篇文章.


ggplot和plotnine


值得一说,对于R迁移过来的人来说,ggplot和plotnine简直是福音,基本克隆了ggplot2所有语法。横向比较的话,plotnine的效果更好。这两个绘图包的底层依旧是matplotlib,因此,在引用时别忘了使用%matplotlib inline语句。值得一说的是plotnine也移植了ggplot2中良好的配置语法和逻辑。


## plotnine示例

( ggplot ( mtcars , aes ( 'wt' , 'mpg' , color = 'factor(gear)' ))

+ geom_point ()

+ stat_smooth ( method = 'lm' )

+ facet_wrap ( '~gear' ))


Seaborn


seaborn准确上说属于matplotlib的扩展包,在其上做了许多非常有用的封装,基本上可以满足大部分统计作图的需求,以matplotlib+seaborn基本可以满足大部分业务场景,语法也更加「陈述式」。


缺点是封装较高,基本上API不提供的图就完全不可绘制,对于各类图的拼合也不适合;此外配置语句语法又回归「命令式」,相对复杂且不一致。


## seaborn示例

import seaborn as sns ; sns . set ( color_codes = True )

iris = sns . load_dataset ( "iris" )

species = iris . pop ( "species" )

g = sns . clustermap ( iris )


plotly


plotly是跨平台JavaScript交互式绘图包,由于开发者的核心是javascript,所以整个语法类似于写json配置,语法特质也介于「陈述式」和「命令式」之间,无服务版本是免费的。


有点是学习成本不高,可以很快将语句移植到javascript版本;缺点是语言相对繁琐。


##plotly示例

import plotly . plotly as py

import plotly . graph_objs as go

# Add data

month = [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' ,

'August' , 'September' , 'October' , 'November' , 'December' ]

high_2000 = [ 32.5 , 37.6 , 49.9 , 53.0 , 69.1 , 75.4 , 76.5 , 76.6 , 70.7 , 60.6 , 45.1 , 29.3 ]

low_2000 = [ 13.8 , 22.3 , 32.5 , 37.2 , 49.9 , 56.1 , 57.7 , 58.3 , 51.2 , 42.8 , 31.6 , 15.9 ]

high_2007 = [ 36.5 , 26.6 , 43.6 , 52.3 , 71.5 , 81.4 , 80.5 , 82.2 , 76.0 , 67.3 , 46.1 , 35.0 ]

low_2007 = [ 23.6 , 14.0 , 27.0 , 36.8 , 47.6 , 57.7 , 58.9 , 61.2 , 53.3 , 48.5 , 31.0 , 23.6 ]

high_2014 = [ 28.8 , 28.5 , 37.0 , 56.8 , 69.7 , 79.7 , 78.5 , 77.8 , 74.1 , 62.6 , 45.3 , 39.9 ]

low_2014 = [ 12.7 , 14.3 , 18.6 , 35.5 , 49.9 , 58.0 , 60.0 , 58.6 , 51.7 , 45.2 , 32.2 , 29.1 ]

# Create and style traces

trace0 = go . Scatter (

x = month ,

y = high_2014 ,

name = 'High 2014' ,

line = dict (

color = ( 'rgb(205, 12, 24)' ),

width = 4 )

)

trace1 = go . Scatter (

x = month ,

y = low_2014 ,

name = 'Low 2014' ,

line = dict (

color = ( 'rgb(22, 96, 167)' ),

width = 4 ,)

)

trace2 = go . Scatter (

x = month ,

y = high_2007 ,

name = 'High 2007' ,

line = dict (

color = ( 'rgb(205, 12, 24)' ),

width = 4 ,

dash = 'dash' ) # dash options include 'dash', 'dot', and 'dashdot'

)

trace3 = go . Scatter (

x = month ,

y = low_2007 ,

name = 'Low 2007' ,

line = dict (

color = ( 'rgb(22, 96, 167)' ),

width = 4 ,

dash = 'dash' )

)

trace4 = go . Scatter (

x = month ,

y = high_2000 ,

name = 'High 2000' ,

line = dict (

color = ( 'rgb(205, 12, 24)' ),

width = 4 ,

dash = 'dot' )

)

trace5 = go . Scatter (

x = month ,

y = low_2000 ,

name = 'Low 2000' ,

line = dict (

color = ( 'rgb(22, 96, 167)' ),

width = 4 ,

dash = 'dot' )

)

data = [ trace0 , trace1 , trace2 , trace3 , trace4 , trace5 ]

# Edit the layout

layout = dict ( title = 'Average High and Low Temperatures in New York' ,

xaxis = dict ( title = 'Month' ),

yaxis = dict ( title = 'Temperature (degrees F)' ),

)

fig = dict ( data = data , layout = layout )

py . iplot ( fig , filename = 'styled-line' )


注意:此框架在jupyter中使用需要使用init_notebook_mode()加载JavaScript框架。


bokeh


bokeh是pydata维护的比较具有潜力的开源交互可视化框架。


值得一说的是,该框架同时提供底层语句和「陈述式」绘图命令。相对来说语法也比较清楚,但其配置语句依旧有很多可视化框架的问题,就是与「陈述式」命令不符,没有合理的结构。此外,一些常见的交互效果都是以底层命令的方式使用的,因此如果要快速实现Dashboard或者作图时就显得较为不便了。


## Bokeh示例

import numpy as np

import scipy . special

from bokeh . layouts import gridplot

from bokeh . plotting import figure , show , output_file

p1 = figure ( title = "Normal Distribution (μ=0, σ=0.5)" , tools = "save" ,

background_fill_color = "#E8DDCB" )

mu , sigma = 0 , 0.5

measured = np . random . normal ( mu , sigma , 1000 )

hist , edges = np . histogram ( measured , density = True , bins = 50 )

x = np . linspace ( - 2 , 2 , 1000 )

pdf = 1 / ( sigma * np . sqrt ( 2 * np . pi )) * np . exp ( - ( x - mu ) ** 2 / ( 2 * sigma ** 2 ))

cdf = ( 1 + scipy . special . erf (( x - mu ) / np . sqrt ( 2 * sigma ** 2 ))) / 2

p1 . quad ( top = hist , bottom







请到「今天看啥」查看全文