[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程

-1 关于plotly 的小问题

因为plotly用着还不熟练,我把我遇到的一些plotly调用问题总结了一下:

  • [打补丁]plotly常见问题

0. 前言:

疫情期间,工作‘过于‘繁忙。。。教程早已编好,文稿却没更出来。。。
(伪)鲁迅曾经说过:所有的数据都应该被‘画’出来,而不是‘写’出来。

自接触数据科学起,我就异常热衷于’画‘出更好的数据图(逼死强迫症)。作为一个曾经的通信人,Matlab告诉我,不能交互的数据图永远不算完美。什么matplotlib,seaborn,甚至ggplot。我只想说,普通。。。直到 plotly出现。

1. plotly介绍

plotly官方文档: https://plotly.com/python

plotly是一个可交互的 开源 开源 开源 python数据可视化库。在顶层通过 JavaScript(plotly.js)库生成web-based 可视化图表。
(可以直接生成网页,还能集成在jupyter-notebook | jupyter-lab(需要额外插件)| VS code 中直接显示)
另外,plotly 作为python 数据生态中的重要一环,也创建了相应的网页数据报表 – Dash ,对标R shiny,Tableau,MS PowerBI(后两个为商业软件,集成环境更优秀,而且价格也挺贵。。。)
[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程_第1张图片

当然, plotly & Dash也分为开源版本商用版本, 并且4.0版本之前都可以使用online/offline 两种模式。其中online模式需要注册账号, 上传的图表可以使用Chart Studio对细节进行更改。 4.0之后的版本已经将online模式彻底移植到 chart-studio 中,

  • 开源版本一切免费,证书为github上的开源证书 – MIT license,No Technical Supports!!(除了bug自己调试 或者等待在下个版本解决)
  • 商用版本各种服务收费,还能使用有UI界面的Chart Studio修图。价格嘛,详情需要自己咨询。。。

1.1 安装

pip 和conda 都可以直接安装, 截止到目前为止 最新版本为 4.6.0 (plotly >=4.0.0 只有offline 模式

pip install plotly==4.6.0

考虑到各个packages 的版本依赖关系, 更推荐通过conda安装

conda install -c plotly plotly==4.6.0

我一直用jupyter-lab, 额外的extensions安装如下 (jupyter 安装extensions 需要提前安装 node.js。。。):

conda install jupyterlab
conda install ipywidgets
jupyter labextension install @jupyter-widgets/[email protected] --no-build
jupyter labextension install [email protected] --no-build
jupyter labextension install [email protected] --no-build
jupyter lab build

1.2 plotly 子模块

在最开始使用plotly的时候,我唯一的一个疑问就是,搞不清楚什么时候使用什么模块。为此,特意去研究了一下官方提供的API教程。

plotly分为 5个重要子模块:

  • express 模块:高级画图API,类似seaborn,可以用简单的代码,通过读取dataframe,画出相对复杂的分布曲线,kde曲线。
  • graph_objects 模块: 底层画图API, 类似 matplotlib.pyplot, 可以精确控制图像中的每一个变量,图像figure的大小,图像布局,曲线的粗细,点击曲线后显示的信息,etc。但是 每一个变量都需要用户自主声明。
  • subplots 模块:用于创建多图布局 类似 pyplot 中的subplots
  • figure_factory 模块: 用于创建特定复杂的图表
  • io模块: input/output模块 用于读取/生成 各种格式的图表 (HTML, json, images, etc…)

2. 数据可视化:

数据来源: 约翰霍普金森大学 - 新冠病毒全球感染人数 - Github 开源数据

编程环境:

  • Python version = 3.8
  • jupyter-lab version = 1.2.6
  • plotly version = 4.6.0
  • numpy version = 1.18.1
  • pandas version = 1.0.3
  • cufflinks version = 0.17.3

2.1 读取数据

# import basic libs
import os 
import pandas as pd
import numpy as np

# 直接从github读取数据
df = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/web-data/data/cases_time.csv', error_bad_lines=False )
df.loc[:,'Last_Update'] = pd.to_datetime(df.loc[:,'Last_Update'], format='%m/%d/%y')
print(df.shape) # output: (21384, 16) 

# 国家/城市坐标 & 人口数据
location_lookup_table = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/UID_ISO_FIPS_LookUp_Table.csv', error_bad_lines=False )

数据基本情况:

# 疫情统计时间
df.loc[:,'Last_Update'].min() # Timestamp('2020-01-22 00:00:00')
df.loc[:,'Last_Update'].max() # Timestamp('2020-04-18 00:00:00')

从时间角度看,基本就是,国内暴发疫情之后的第一阶段。

2.2 创建画布

就像写网页需要CSS布局文件一样,Plotly也需要先创建一个布局 Layout
Plotly是用js 编译生成图像, 配置文件 基本就是json格式,所以各个参数可以用字典直接定义。

下面的例子里,我简单的设定了一些常用的参数,方便直接copy 使用

import plotly as py
from plotly import graph_objects as go
from plotly import subplots

layout_default = go.Layout(
	# color theme
	template='plotly_dark',
	
    # set title
    title = dict(
        text='Default Title',
        font={
            'size':30,
            'color':'#444'
        },
        x=0.5, #[0,1,'auto']
        y=0.9 # [0,1, 'auto']
    ),
    
    # set axis
    xaxis=dict(
        visible=True,
        color='#444',
        title='default xaxis' # or dict
    ),
    yaxis=dict(
        visible=True,
        color='#444',
        title='default yaxis', # or dict
        type='-', # one of ( "-" | "linear" | "log" | "date" | "category" | "multicategory" )
        #range=[1,2]
    ),
    
    # set Figure's size
    autosize=False,
    height=600, # in pixel
    width=1100,
    
    # set Legend
    showlegend=True
)

2.3 欧洲各国的累计感染人数曲线

# 准备数据
countries = ['DEU', 'ESP', 'FRA', 'GBR', 'ITA', 'USA']
df_country = df[(df['Province_State'].isna())&(df['Last_Update'] >= '2020-03-01')]

# pivot 各个国家的确诊人数
data= df_country.pivot_table(index='iso3',columns='Last_Update',values='Confirmed', fill_value=0, aggfunc='mean').loc[countries]

# 创建 figure
fig = go.Figure(layout=layout_default)
# x坐标
x= data.columns.strftime('%Y-%m-%d').values.tolist()

# 画多条曲线
for idx in data.index:
    # 官方API: https://plotly.com/python/reference/
    fig.add_trace(
        go.Scatter(
            x =x,
            y = data.loc[idx].values.tolist(),
            text = data.loc[idx].values.tolist(),
            mode = 'lines+markers',
            name= location_lookup_table[location_lookup_table['iso3'] == idx].iloc[0]['Country_Region'],
            hovertext = 'Population:{}'.format(int(location_lookup_table[location_lookup_table['iso3'] == idx].iloc[0]['Population'])),
            hoverinfo = 'all',# Examples: "x", "y", "x+y", "x+y+z", "all"
            opacity=0.5
        )
    )

# 略微更改一下布局
fig.update_layout(
    title = dict(
        text='疫情大国确诊总人数',
        font={'size':30},
        x=0.5, #[0,1,'auto']
        y=0.9 # [0,1, 'auto']
    ),
)

# 快速更改axis
fig.update_xaxes(
    title_text="日期 加粗"
)

fig.update_yaxes(
    title_text="确诊人数 斜体"
)

# 画图像
fig.show()

如下图:
[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程_第2张图片

2.4 感染严重程度以及发展情况

看了其他的API, 我发现如果要创建多个子图的画布, 最好还是直接从底层graph_objects 配合 subpots 来搭建更快捷.
如果需求仅仅是EDA过程中的数据可视化 那么 plotly.express很好的适配了pandas.DataFrame, 真的真的真的很方便!

import plotly.express as px

fig = px.scatter_geo(data_frame=df_country, 
                     locations="iso3", 
                     color="Incident_Rate",
                     hover_name="Country_Region", 
                     size="Confirmed",
                     animation_frame=df_country["Last_Update"].astype(str),
                     projection="natural earth",
                     size_max=100,
                     width=1200, height=700)
fig.update_layout(
    template='plotly_dark'
)
fig.show()

输出截图(真的不会添加本地动图。。。)
[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程_第3张图片

2.5 其他

  • 表格 Table
    当然,除了图像绘制以外, plotly还可以显示表格, 我写了一个将df转换为plotly表格的function
# pandas.dataframe --> plotly.graph_objects.table 
def TableFromPandas(df):
    columns = df.columns
    return go.Table(
        header=dict(values=list(columns),
                    align='left'),
        cells=dict(values=[df[i] for i in columns],
                   align='left')
    )   
fig = go.Figure(
    data=[TableFromPandas(df_country)]
) 

fig.show()

[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程_第4张图片

2.6 总结

其实 总体看起来,plotly底层API graph_objects参数繁多,可操作空间非常大, 配合subplots,可以制作出非常精良的报表!
用于EDA过程中的数据可视化却略有些繁琐。相对而言, plotly.express在平时相对更加实用!

另外还有一个package 叫做 cufflinks 日常用起来更加方便, 可以通过 df.iplot() 直接调用plotly API , 平时用来画些简单的分布图啊, 折线图啊 只能是真香 !

import cufflinks as cf
cf.go_offline()
cf.set_config_file(offline=False, world_readable=True)

# 数据没变
df_country.pivot_table(columns='iso3',index='Last_Update',values='Confirmed', fill_value=0, aggfunc='mean')[countries].iplot(opacity=0.5, mode = 'lines')

[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程_第5张图片


下次更新内容:

  • 传统时序模型
  • 美股股指, 个股, 美债 走势分析

What’s More

PS : 话说,曾经用Dash制作过一个简单的审阅学生考试成绩的报表,只不过是法语版的,有需要的朋友可以拿走:
https://github.com/lhaippp/Dash_Student_Management_System

PPS:上周收到了祖国爸爸发来的急救包(不是只给留学生 lol)!口罩,莲花清瘟胶囊,消毒湿巾一应俱全。一看日期,3月23号生产!从生产到运输直到送达, 在没有物流的情况下,10多天就能全球达!

我要吹一波!!
[数据科学]001.新冠病毒全球疫情-数据可视化-plotly-完整详尽教程_第6张图片

你可能感兴趣的:(Data,Talk,数据炼金指南)