一学就会,20000字深度讲解 Python 数据可视化神器 Plotly

Posted Python学习与数据挖掘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一学就会,20000字深度讲解 Python 数据可视化神器 Plotly相关的知识,希望对你有一定的参考价值。

作为 Python 的新一代数据可视化绘图库,和matplotlib等传统绘图库相比,plotly具有以下优点:

  • 简洁易用: 作为一只小透明,plotly的图表对象就像一个嵌套dict, 可以通过直接修改对象属性而改变图表形态。学习难度远远小于matplotlib.

  • 动态交互: plotly绘制的图都是可以交互的图表,可以点击查看数据,拖拽放大,隐藏某些数据列等等,也可以导出成静态图,灵活性大大增加。

  • 前端能力: 基于plotly和React开发的Dash号称是 The front end for ML and data science models,可以基于它用Python轻松构建机器学习应用App.

通常,plotly有两种常用的绘图接口:

  • 第一种是面向对象的绘图接口:plotly.graph_objs(简称go),也是最基础的绘图接口,

  • 第二种是面向函数式的快速绘图接口: plotly.express(简称px),是在go基础上封装的一种更方便的绘图接口。

本文我们按照如下3 part来深入浅出地讲解plotly的使用方法。喜欢记得收藏、关注、点赞

  • part1: 深入原理, 本文第一节和第二节,分别介绍 go和px 的设计思想和绘图原理。

  • part2: 浅出范例, 本文第三节和第四节,对比性地展示 go和px 的五种绘图范例(柱形图、折线图、散点图、热力图、直方图)

  • part3: 深入实践, 本文第五节,展示一些plotly和机器学习相结合的综合应用范例。

注:完整代码、资料、技术交流,文末提供

一,plotly.graph_objs绘图原理

plotly的Figure是由data(数据,数据包括图表类型(Line,Scatter,Area,Pie)和具体数据取值信息)和 layout(布局,包括xaxis,yaxis,title,legend等) 组成的对象。

Figure对象就像一个透明的嵌套的Python dict 一样,可以通过修改元素值而改变其形态。

import numpy as np 
import plotly.graph_objs as go

epoches = np.arange(20)
accs = 1-0.9/(epoches+1)

data = go.Scatter(x = epoches, y=accs, mode = "lines+markers",name = "acc",
                    marker = dict(size=8,color="blue"),
                    line= dict(width=2,color="blue",dash="dash"))

layout = "title":"accuracy via epoch",
          "xaxis.title":"epoch",
          "yaxis.title":"accuracy",
          "font.size":15

fig = go.Figure(data = data,layout=layout)
fig.show() 

如果要把图表的颜色改成红色实线怎么办呢?很简单,我们先print(fig)一下,观察它的结构,找到线的颜色和线型的属性获取方法,然后直接对相应属性赋值就可以了。

print(fig.data)  #如果想获取fig更详细结构信息,可以直接 fig.to_dict()

(Scatter(
'line': 'color': 'blue', 'dash': 'dash', 'width': 2,
'marker': 'color': 'blue', 'size': 8,
'mode': 'lines+markers',
'name': 'acc',
'x': array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19]),
'y': array([0.1       , 0.55      , 0.7       , 0.775     , 0.82      , 0.85      ,
0.87142857, 0.8875    , 0.9       , 0.91      , 0.91818182, 0.925     ,
0.93076923, 0.93571429, 0.94      , 0.94375   , 0.94705882, 0.95      ,
0.95263158, 0.955     ])
),)
fig.data[0].line.color = "red"
fig.data[0].line.dash = "solid"
fig 

怎么样,plotly是不是一个当之无愧的小透明。😝

以上这种直接对一个Figure对象的属性的值的修改方法多少显得有些粗暴,不够尊重小透明。

实际上,plotly的Figure对象提供了 fig.update_layout 和 fig.update_data 这样的方法来让 小透明面对突如其来的修改时候显得更加体面一些。

import numpy as np 
import plotly.graph_objs as go
epoches = np.arange(20)
accs = 1-0.9/(epoches+1)
fig = go.Figure(data = go.Scatter(x = epoches, y=accs, mode = "lines+markers",name = "acc",
                    marker = dict(size=8,color="blue"),
                    line= dict(width=2,color="blue",dash="dash")))
fig.show() 

fig.update_traces(patch="line.color":"red","line.dash":"solid",selector=dict(name="acc"))
fig.update_layout("title":"accuracy via epoch",
          "xaxis.title":"epoch",
          "yaxis.title":"accuracy",
          "font.size":15)
fig.show() 

二,plotly.express绘图原理

使用 import plotly.graph_objs as go 的go接口来绘制图表实际上已经非常简单了,一般类型的图表三五行代码就可以搞定。

但我还是想偷懒,能否一行代码就搞定大部分常用图表呢。

当然可以,plotly.express就是为你准备的。英文单词express 意为 快线,特快列车。就像营养快线的英文,Nutri-express.

plotly.express的原理非常简单,Figure不是主要由 data(traces)和layout组成嘛。

data部分传入一个pandas的DataFrame,而layout部分可以用模板template指定嘛,一行代码搞定。

当然有时候template的一些微观形态可能与用户想要的还不完全一样,将生成的Figure当做小透明直接修改属性即可。

import plotly.express as px 
import numpy as np 
import pandas as pd 

dfdata = pd.DataFrame("epoch":np.arange(20),"accuracy":1-0.9/(np.arange(20)+1))
fig = px.line(data_frame=dfdata,x="epoch",y="accuracy",title="accuracy via epoch")
fig.show() 

可以看到,plotly.express已经帮我们把坐标轴标题什么的都设置好了。

但是整体看起来还是有些不太美观,多大的事呀,分分钟修改小透明!

fig.update_traces(patch=dict(mode = "lines+markers",
                    marker = dict(size=8,color="blue"),
                    line= dict(width=2,color="red",dash="solid")),
                  selector=dict(type="scatter")) #用patch指定补丁,用selector指定对那个数据打补丁
fig.update_layout("font.size":15)
fig.show() 

除了精细地修改Figure属性的话,我们想改变Figure样貌的更加快捷的方式是换一个模板(template)

import plotly 
print(plotly.io.templates) 
fig.layout.template = "seaborn" 
fig 

Templates configuration
-----------------------
    Default template: 'plotly'
    Available templates:
        ['ggplot2', 'seaborn', 'simple_white', 'plotly',
         'plotly_white', 'plotly_dark', 'presentation', 'xgridoff',
         'ygridoff', 'gridon', 'none']

三,常用图表go绘图范例

plotly支持的图表类型非常丰富,包括各种基础图表,统计图表,金融图表,机器学习图表,地图图表,and more.

详情参考 https://plotly.com/python/ 中的gallery范例。

此处只介绍最基础最常用的5种基础图表类型:柱形图、折线图、散点图、热力图、直方图。

我们先用go接口展示绘图范例,然后作为比较,用px接口再实现一遍。

1,柱形图

柱形图适合表现几组数据之间的对比关系,柱形图的数据的数量一般不宜太多。

import pandas as pd 
import plotly.graph_objs as go

x = ["f1", "f2", "f3", "f4", "f5"]
y1 = [5, 20, 36, 10, 75]
y2 = [10, 25, 8, 60, 20]

traceA = go.Bar(x=x,y=y1,name="模型A")
traceB = go.Bar(x=x,y=y2,name="模型B")
layout = go.Layout(title="特征重要性分析",xaxis="title":"特征",
    yaxis="title":"重要性",barmode="group") #barmode is one of "relative","overlay","group"

fig = go.Figure(data = [traceA,traceB],layout=layout)
fig.show() 


# 互换 x轴 和 y轴含义,orientation设置为horizontal,变成水平条形图
import pandas as pd 
import plotly.graph_objs as go

x = ["f1", "f2", "f3", "f4", "f5"]
y1 = [5, 20, 36, 10, 75]
y2 = [10, 25, 8, 60, 20]

traceA = go.Bar(x=y1,y=x,name="模型A",orientation='h')
traceB = go.Bar(x=y2,y=x,name="模型B",orientation='h')
layout = go.Layout(title="特征重要性分析",xaxis="title":"重要性",
    yaxis="title":"特征",barmode="group") #barmode is one of "relative","overlay","group"

fig = go.Figure(data = [traceA,traceB],layout=layout)
fig.show() 

2,折线图

折线图适合描述两个变量之间的函数关系,例如常用它来描述一个变量随时间的变化趋势。

import pandas as pd 
import plotly.graph_objs as go

dates = ['2021-:0>2d'.format(s) for s in range(1,13)]
acc = [70,72,80,65,76,80,60,67,80,90,94,82]
recall = [65,42,35,25,67,54,34,45,38,46,64,34]

fig = go.Figure()
fig.add_trace(go.Scatter(x=dates,y=acc,name="准确率",mode = "lines+markers"))
fig.add_trace(go.Scatter(x=dates,y=recall,name="召回率",mode = "lines+markers"))
fig.update_layout("title":"线上模型表现变化趋势","xaxis.title":"月份","yaxis.title":"指标")
fig.update_layout("font":"size":15)
fig.show() 

#以上图表中的x轴刻度被自动换成了英文时间,不是很方便识别,使用如下设置直接指定刻度位置和刻度显示内容。
fig.update_layout(
    xaxis = dict(tickmode='array', 
                 tickvals = x,    
                 ticktext = x,     
                 tickangle = 60
    )
)
fig.show() 

3,散点图

散点图适合表现大量样本的多个属性的分布规律。散点图的每个点表示一个样本,每个坐标维度表示一个属性。

当样本属性维度多于2个时,可以使用点的颜色或大小等方式来表达更多属性维度。

import pandas as pd 
import plotly.graph_objs as go

dfboy = pd.DataFrame()
dfboy['weight'] = [56,67,65,70,57,60,80,85,76,64]
dfboy['height'] = [162,170,168,172,168,172,180,176,178,170]
dfboy["BMI"] =  dfboy["weight"]/(dfboy["height"]**2)

dfgirl = pd.DataFrame()
dfgirl['weight'] = [50,62,60,70,57,45,62,65,70,56]
dfgirl['height'] = [155,162,165,170,166,158,160,170,172,165]
dfgirl["gender"] = "female"
dfgirl["BMI"] = dfgirl["weight"]/(dfgirl["height"]**2)


trace1 = go.Scatter(x=dfboy["weight"],y=dfboy["height"],mode="markers",name="male",
                     marker = dict(color="blue",size=3e5*dfboy["BMI"],sizemode='area'))

trace2 = go.Scatter(x=dfgirl["weight"],y=dfgirl["height"],mode="markers",name="female",
                   marker = dict(color="red",size=3e5*dfgirl["BMI"],
                                 sizemode='area'))

layout = go.Layout("title":"height & weight",
                    "xaxis.title":"weight",
                    "yaxis.title":"height",
                    "legend.title":"gender",
                    "font.size":15)

fig = go.Figure(data=[trace1,trace2],layout=layout)
fig.show() 

4,热力图

热力图可以直观地展示一个二维矩阵的取值,它将一个矩阵的每个元素取值对应到热力图上的一个像素颜色取值。

import numpy as np 
import plotly.graph_objs as go

arr = np.random.normal(loc = 0,scale = 1,size = [10,10])
trace = go.Heatmap(x=np.arange(10),y=np.arange(10),z=arr,
                   colorscale='Viridis',showscale=True,reversescale = False)
layout = go.Layout(width=600, height=600)
fig = go.Figure(data=trace,layout=layout) 
fig.show() 

5,直方图

直方图适合呈现一组数据的统计分布规律,它计算这组数据落在各个小的分段区间的样本个数并用类似柱状图的方式展示出来。

import numpy as np 
import plotly.graph_objs as go 
scores = np.random.randint(low=0,high=100,size = 1000)

trace = go.Histogram(x=scores,histnorm = 'density',nbinsx=60)
fig = go.Figure(trace)
fig.update_layout("title":"Score Distribution","xaxis.title":"score","yaxis.title":"frequency","template":"seaborn")
fig.show() 

四,常用图表px绘图范例

作为对比,下面使用plotly.express接口绘制5种最常用的基础图表:

柱形图、折线图、散点图、热力图、直方图。

1,柱形图

柱形图适合表现几组数据之间的对比关系,柱形图的数据的数量一般不宜太多。

import pandas as pd 
import plotly.express as px 

x = ["f1", "f2", "f3", "f4", "f5"]
y1 = [5, 20, 36, 10, 75]
y2 = [10, 25, 8, 60, 20]
df=pd.DataFrame(以上是关于一学就会,20000字深度讲解 Python 数据可视化神器 Plotly的主要内容,如果未能解决你的问题,请参考以下文章

一学就会,手把手教你用Go语言调用智能合约

满天星空小游戏—小白一学就会的python游戏开发实战源码+教程

一学就会的便签整理法 帮你轻松收集灵感

麻省理工教授良心总结,Python的学习方法 学习笔记教程都在这里 ,一学就会

麻省理工教授良心总结,Python的学习方法 学习笔记教程都在这里 ,一学就会

Excel行列实用技巧,超级实用,一学就会!