Jupyter 常见可视化框架的选择

文末有福利!


对于以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=0, left=edges[:-1], right=edges[1:],

        fill_color="#036564", line_color="#033649")

p1.line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")

p1.line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")

 

p1.legend.location = "center_right"

p1.legend.background_fill_color = "darkgrey"

p1.xaxis.axis_label = 'x'

p1.yaxis.axis_label = 'Pr(x)'

 

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

            background_fill_color="#E8DDCB")

 

mu, sigma = 0, 0.5

 

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

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

 

x = np.linspace(0.0001, 8.0, 1000)

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

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

 

p2.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],

        fill_color="#036564", line_color="#033649")

p2.line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")

p2.line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")

 

p2.legend.location = "center_right"

p2.legend.background_fill_color = "darkgrey"

p2.xaxis.axis_label = 'x'

p2.yaxis.axis_label = 'Pr(x)'

 

p3 = figure(title="Gamma Distribution (k=1, θ=2)", tools="save",

            background_fill_color="#E8DDCB")

 

k, theta = 1.0, 2.0

 

measured = np.random.gamma(k, theta, 1000)

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

 

x = np.linspace(0.0001, 20.0, 1000)

pdf = x**(k-1) * np.exp(-x/theta) / (theta**k * scipy.special.gamma(k))

cdf = scipy.special.gammainc(k, x/theta) / scipy.special.gamma(k)

 

p3.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],

        fill_color="#036564", line_color="#033649")

p3.line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")

p3.line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")

 

p3.legend.location = "center_right"

p3.legend.background_fill_color = "darkgrey"

p3.xaxis.axis_label = 'x'

p3.yaxis.axis_label = 'Pr(x)'

 

p4 = figure(title="Weibull Distribution (λ=1, k=1.25)", tools="save",

            background_fill_color="#E8DDCB")

 

lam, k = 1, 1.25

 

measured = lam*(-np.log(np.random.uniform(0, 1, 1000)))**(1/k)

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

 

x = np.linspace(0.0001, 8, 1000)

pdf = (k/lam)*(x/lam)**(k-1) * np.exp(-(x/lam)**k)

cdf = 1 - np.exp(-(x/lam)**k)

 

p4.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],

       fill_color="#036564", line_color="#033649")

p4.line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")

p4.line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")

 

p4.legend.location = "center_right"

p4.legend.background_fill_color = "darkgrey"

p4.xaxis.axis_label = 'x'

p4.yaxis.axis_label = 'Pr(x)'

 

output_file('histogram.html', title="histogram.py example")

 

show(gridplot(p1,p2,p3,p4, ncols=2, plot_width=400, plot_height=400, toolbar_location=None))



其他特殊需求的作图


除了统计作图,网络可视化和GIS可视化也是很常用的,在此只做一个简单的罗列:


GIS类:


  • gmap:交互,使用google maps接口

  • ipyleaflet:交互,使用leaflet接口


网络类:


  • networkx:底层为matplotlib

  • plotly


总结



来源:三次方根

segmentfault.com/a/1190000011831228


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AOP(面向切面编程)大概了解一下

前言上一篇在聊MemoryCache的时候,用到了Autofac提供的拦截器进行面向切面编程,很明显能体会到其优势,既然涉及到了,那就趁热打铁,一起来探探面向切面编程。正文1. 概述在软件业,AOP为Aspect Oriented Prog…

机器学习三部曲

随着科技的发展,计算机对人类的生产活动和社会活动产生了极为重要的影响,同时以强大的生命力飞速发展着。目前计算机正广泛用于社会各个领域,并朝着微型化、网络化、智能化和巨型化的方向前进。说到智能化,大家最先想到的应该就是…

AntDesign Pro + .NET Core 实现基于JWT的登录认证

很多同学说AgileConfig的UI实在是太丑了。我想想也是的,本来这个项目是我自己使用的,一开始甚至连UI都没有,全靠手动在数据库里修改数据。后来加上了UI也是使用了老掉牙的bootstrap3做为基础样式。前台框架也是使用了angularjs,同…

武汉大学计算机学院2019考研复试,2019年武汉大学硕士研究生复试及录取名单汇总...

原标题:2019年武汉大学硕士研究生复试及录取名单汇总考生可以通过录取名单了解到很多重要的信息,例如复试比例,进复试最低分,复试录取成绩,录取总评成绩等重要信息。以下是我们整理收集到的各学院复试录取名单汇总&…

ugui unity 取消选择_UGUI中几种不规则按钮的实现方式

前言UGUI中的按钮默认是矩形的,若要实现非矩形按钮该怎么做呢?比如这样的按钮:本文将介绍两种实现方式供大家选择。使用alphaHitTestMinimumThresholdImage类的alphaHitTestMinimumThreshold是一个浮点值,Raycast检测时只有图片中…

你的专业 VS 你妈口中你的专业

亲妈认证★英语语言文学我妈:她就是一个学英语的~我同学:你学英语的啊?那你看美剧不用看字幕的吧?你听英文歌都听得懂的吧?这个怎么翻译啊?这上面写的什么?你不是专八吗?哈喽~ 在吗&…

反射 + 抽象工厂模式切换不同的实现方法

概述工厂模式(Abstract Factory)定义 :提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其…

3 年工作经验程序员应有的技能

前言因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章。这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发的,因此有一部分内容也是专门面向咱们Java程序员的。第二阶段:五年五…

应急响应中的溯源方法

在发现有入侵者后,快速由守转攻,进行精准地溯源反制,收集攻击路径和攻击者身份信息,勾勒出完整的攻击者画像。 对内溯源与对内溯源 对内溯源:确认攻击者的行为 ,分析日志 数据包等; 对外溯源&…

POP3口令扫描案例

通过本案例可以学到: (1)了解POP3有关知识(2)利用Hscan工具软件来破解POP3账号和口令现在很多邮箱服务器都支持POP3功能,通过POP3来收取信件,收取信件时仅仅需要提供用户名和密码。目前有很多工具可以扫描POP3邮件账号和口令,本案…

中connect怎么用_烘焙中的各种酒,到底该怎么用?

​在烘焙食谱中,经常会出现“酒”这样材料。烘焙中的酒,仿佛是个神秘的存在,品种也繁多得让人一脸懵逼,朗姆酒是干嘛用的?怎么还有分白朗姆和金朗姆?和利口酒有什么区别?利口酒和力娇酒是同一个…

QQ旋风爆缓冲区溢出漏洞

据金山毒霸安全实验室5月7日透露,金山毒霸安全实验室研究人员进行例行漏洞检查过程中,发现QQ旋风存在一鲜为人知的缓冲区溢出0day漏洞,***者可以利用该漏洞制造恶意URL,使用IE6,7内核的各种浏览器均会受此漏洞的影响。…

w10计算机无法打印,win10升级后惠普无法打印怎么解决_win10升级后惠普打印不了的处理办法...

使用电脑工作或学习时,我们经常会需要用到打印机。可是最近有一些网友却反映说,自己的win10电脑在升级后出现了惠普无法打印的情况,这是怎么一回事呢?我们又该怎么解决呢?用户不是很清楚,所以对此今天本文为…

女神节爆猛料!. NET程序员男女比例公布!

今天是三八女神节,这里先祝广大的程序员妹子们节日快乐,健康美丽!有一个问题,相信很多.NET程序员都很感兴趣:.NET程序员中女生占比多少?先来公布答案:在本次调查中发现,.NET程序员群…

金蝶凭证序时簿在哪_来了!金蝶日常账务处理大全

上一期给宝宝们更新了金蝶软件建账的一些处理流程,宝宝们已经迫不及待要求后续了。在日常处理部分主要是以下几个方面一、凭证审核1.凭证录入点击主窗口中的【凭证】,单击【凭证】录入在凭证录入窗口中单击【凭证录入】按钮,在这个窗口中就可…

在C#中使用SQLite

SQLite 是一个嵌入式的关系数据库系统,使用十分广泛。在一些数据量不大的应用程序中,如果使用SQLite可以极大的减少部署时的工作量。 要在C#中使用SQLite也很简单,只要找一个C#的wrapper就可以了,例如,我使用的就是来自…

BI 界震动 - Power BI Premium 个人版只要每月 120 元

大事来了就在今天,微软宣布:Power BI Premium Per User 定价:每月 120 元人民币。我只能说:他没有骗人。Power BI 团队也在这个战略决策上符合了微软的核心使命。这一举措将更加彻底的巩固微软 Power BI 的商业智能帝国地位&#…

用 Python 实现一个大数据搜索引擎

搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。布隆过滤器 (Bloom Filter)第一步我们先要实现一个布隆…

iNeuOS工业互联操作系统,图表与数据点组合成新组件,进行项目复用

目 录1. 概述... 12. 演示信息... 23. 应用过程... 21. 概述针对有些行业的数据已经形成了标准化的建模或者有些公司专注于某个领域,对于开发业务有很多情况需求进行复用,以前的版本和文章介绍了图元及数据点的组合形成新的图元进…

通过对象属性去重_Redis常见对象类型的底层数据结构

作者:伍陆七来源:cnblogs.com/chentianming/p/13838347.htmlRedis 是一个基于内存中的数据结构存储系统,可以用作数据库、缓存和消息中间件。Redis 支持五种常见对象类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)以及有…