整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

50行Python代码绘制数据大屏,这个可视化框架真的太神了

者: 俊欣

来源:关于数据分析与可视化

今天小编来为大家安利另外一个用于绘制可视化图表的Python框架,名叫Dash,建立在FlaskPlotly.js以及React.js的基础之上,在创建之出的目的是为了帮助前端知识匮乏的数据分析人员,以纯Python编程的方式快速制作出交互特性强的数据可视化大屏,在经过多年的迭代发展,如今不仅仅可以用来开发在线数据可视化作品,即便是轻量级的数据仪表盘、BI应用甚至是博客或者是常规的网站都随处可见Dash框架的影子,今天小编就先来介绍一下该框架的一些基础知识,并且来制作一个简单的数据可视化大屏。

Dash框架中的两个基本概念

我们先来了解一下Dash框架中的两个基本概念

  • Layout
  • Callbacks

Layout顾名思义就是用来设计可视化大屏的外观和布局,添加一些例如下拉框、单选框、复选框、输入框、文本框、滑动条等组件,其中Dash框架对HTML标签也进行了进一步的封装,使得我们直接可以通过Python代码来生成和设计每一个网页所需要的元素,例如

<div>
    <h1>Hello World!!</h1>
    <div>
        <p>Dash converts Python classes into HTML</p>
    </div>
</div>

我们转化成DashPython结构就是

html.Div([
    html.H1('Hello Dash'),
    html.Div([
        html.P('Dash converts Python classes into HTML'),
    ])
])

Callbacks也就是回调函数,基本上是以装饰器的形式来体现的,实现前后端异步通信的交互,例如我们在点击按钮或者下拉框之后出现的功能就是通过回调函数来实现的。

安装和导入模块

在导入模块之前,我们先用pip命令来进行安装,

! pip install dash   
! pip install dash-html-components
! pip install dash-core-components                           
! pip install plotly

然后我们导入这些刚刚安装完的模块,其中dash-html-components用来生成HTML标签,dash-core-components模块用来生成例如下拉框、输入框等组件,这里我们还需要用到plotly模块,因为我们需要用到的数据来自该模块,里面是一众互联网公司过去一段时间中股价的走势

import dash
import dash_html_components as html
import dash_core_components as dcc
import plotly.graph_objects as go
import plotly.express as px

读取数据并且绘制折线图

那么我们读取数据并且用plotly来绘制折线图,代码如下

app = dash.Dash()   #实例化Dash
df = px.data.stocks() #读取股票数据 

def stock_prices():
    # 绘制折线图
    fig = go.Figure([go.Scatter(x=df['date'], y=df['AAPL'],
                                line=dict(color='firebrick', width=4), name='Apple')
                     ])
    fig.update_layout(title='股价随着时间的变幻',
                      xaxis_title='日期',
                      yaxis_title='价格'
                      )
    return fig
    
app.layout = html.Div(id='parent', children=[
    html.H1(id='H1', children='Dash 案例一', style={'textAlign': 'center',
                                                 'marginTop': 40, 'marginBottom': 40}),
    dcc.Graph(id='line_plot', figure=stock_prices())
])

if __name__ == '__main__':
    app.run_server()

我们点击运行之后会按照提示将url复制到浏览器当中便可以看到出来的结果了,如下所示

从代码的逻辑上来看,我们通过Dash框架中的Div方法来进行页面的布局,其中有参数id来指定网页中的元素,以及style参数来进行样式的设计,最后我们将会指出来的图表放在dcc.Graph()函数当中。

添置一个下拉框

然后我们再添置一个下拉框,当我们点击这个下拉框的时候,可是根据我们的选择展示不同公司的股价,代码如下

dcc.Dropdown(id='dropdown',
             options=[
                 {'label': '谷歌', 'value': 'GOOG'},
                 {'label': '苹果', 'value': 'AAPL'},
                 {'label': '亚马逊', 'value': 'AMZN'},
             ],
             value='GOOG'),

output

options参数中的label对应的是下拉框中的各个标签,而value对应的是DataFrame当中的列名

df.head()

output

添加回调函数

最后我们将下拉框和绘制折线图的函数给连接起来,我们点击下拉框选中不同的选项的时候,折线图也会相应的产生变化,

@app.callback(Output(component_id='bar_plot', component_property='figure'),
              [Input(component_id='dropdown', component_property='value')])
def graph_update(dropdown_value):
    print(dropdown_value)
    # Function for creating line chart showing Google stock prices over time
    fig = go.Figure([go.Scatter(x=df['date'], y=df['{}'.format(dropdown_value)],
                                line=dict(color='firebrick', width=4))
                     ])
    fig.update_layout(title='股价随着时间的变幻',
                      xaxis_title='日期',
                      yaxis_title='价格'
                      )
    return fig

我们看到callback()方法中指定输入和输出的媒介,其中Input参数,里面的component_id对应的是下拉框的id也就是dropdown,而Output参数,当中的component_id对应的是折线图的id也就是bar_plot,我们来看一下最后出来的结果如下

最后,全部的代码如下所示

周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进 Python 技术,并增长职业和副业的收入。

分享了 10 篇文章,13 个开源项目,2 则热门话题,全文 2100 字。

以下是本期摘要:

文章&教程

① 用 Vue 和 Django 开发 Web 项目的终极指南(2024)

② 用 Pyodide 和 React 开发可视化的低/无代码应用

③ Python __all__的问题

④ 为什么“python -m json”没用?为什么是“json.tool”?

⑤ tea-tasting:对 A/B 测试作统计分析的 Python 包

⑥ 独立线程中的 Asyncio 事件循环

⑦ 使用 eBPF 检测 Python GIL

⑧ 嵌入式 Python:MicroPython 太棒了

⑨ 用 git log 查看 Python 函数的变更记录

⑩ OpenCV 和野生王国

️项目&资源

① fasthtml:最快开发 HTML 应用的方法

② datachain:使用本地 ML 和 LLM 来处理非结构化数据

③ 《数据科学的要素》在线电子书

④ treescope:IPython 笔记本中将 HTML 内容作交互式查看

⑤ cardie:开源的名片设计和分享平台

⑥ PyDPainter:好用的像素艺术绘画工具

⑦ cloudflare-noip:免费替代付费的动态 DNS 服务

⑧ peerfetch:基于 WebRTC 的点对点 HTTP

⑨ yark:让 YouTube 存档变得简单

⑩ patchwork:用 LLM 自动审查代码、改 BUG 和写文档

⑪ RestrictedPython:运行不可信 Python 代码的受限执行环境

⑫ metahuman-stream:实时互动的流媒体数字人

⑬ Chenyme-AAVT:全自动音视频翻译项目

讨论&问题

① 为什么“显性优于隐性”原则不管用了?

② 有哪些小众但好用的 Python 库?


目前周刊实行付费订阅制,年费 128 元,平均每天不到 4 毛钱,但绝对是一笔有眼光的投资。花钱学习知识,花钱提升自己,欢迎订阅这个:你绝对不会后悔的专栏

订阅后,可免费查看 第 63 期周刊的全文

PS.本周刊前30期的合集永久免费,已集结出了精美电子书(EPUB/PDF),请从该合集文章开头获取下载链接。

另外,付费期数将在其 50 期后免费开放,例如第 63 期将在第 113 期时免费,敬请留意。

ython数据分析师工作拓展助手,在不用掌握复杂的HTML、JavaScript、CSS等前端技术的情况下,也能快速做出来一个炫酷的Web APP,把数据分析结果可视化呈现出来!本文推荐Python界新秀,高速发展的开源Web框架Streamlit,与Python界较优秀交互式可视化工具Plotly,组合搭建的"Web数据可视化低代码纯python技术解决方案"。

1. 方案概述

Web数据可视化低代码纯python技术解决方案,是采用Streamlit Web框架,其可视化工具默认使用Bokeh,可以同时兼容使用Plotly、Matplotlib等,前端底层为React.js框架,Web服务端底层为Tornado。

  • 计算架构层采用Pandas、SKlearn、Tensorflow、Python等。其中,数据可视化主要是通过Pandas与Plotly、Streamlit无缝结合;
  • 可视化层以plotly为主,辅以默认的bokeh和matplotlib,以及Streamlit table与MarkDown等。

注:图中灰色背景的终端层,Python数据分析师可以不必关心,已经由Web框架Streamlit封装成低代码python开发接口实现。

1. Web 布局与导航

1.1. 简易快速布局

Streamlit框架提供几种界面布局模板,在这里使用常用的左右单页面结构,如下图所示左侧为Sidebar,对应的API表示为:

st.sidebar.[element_name]

其中,element_name是指交互组件名称,包括:

如上图所示,接下来将以此页面布局开始开发。

1.2. 开始"菜单/导航"

使用单页面结构中的Sidebar为导航控制栏,

import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go

def Layouts_plotly():
    st.sidebar.write('导航栏')
    add_selectbox = st.sidebar.radio(
        "plotly基本图",
        ("Bubble", "Scatter", "Line","aggregate_bar","bar_charts","pie","pulled_out")
    )
    if add_selectbox=="Bubble":
        Bubble()
    elif add_selectbox=="Scatter": 
        Scatter() 
    elif add_selectbox == "Line":
        Line()
    elif add_selectbox == "aggregate_bar":    
        aggregate_bar()
    elif add_selectbox == "bar_charts":    
        bar_charts()
    elif add_selectbox == "pie":     
        pie()
    elif add_selectbox == "pulled_out":
        pulled_out()
    # 补充表单
    st.sidebar.button('基本数据表',on_click=Double_coordinates)

def main():
    Layouts_plotly()
    
if __name__ == "__main__":
    main()

运行程序:streamlit run Demo_plotly_Basic_Charts.py

输入效果如下图所示:

注:框架默认执行第一选项: Bubble(),将在后面补充代码

2. Plotly基本图

def Bubble():       
    df = px.data.gapminder()
    
    fig = px.scatter(df.query("year==2007"), x="gdpPercap", y="lifeExp",
              size="pop", color="continent",
                     hover_name="country", log_x=True, size_max=60)
    # Plot the data
    st.plotly_chart(fig)
     
def Scatter():
    fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
    
    # Plot the data
    st.plotly_chart(fig)
       
def Line():
    df = px.data.stocks()
    fig = px.line(df, x='date', y="GOOG")
    st.plotly_chart(fig)
   
def aggregate_bar():
    df = px.data.tips()
    fig = px.histogram(df, x="sex", y="total_bill",
                 color='smoker', barmode='group',
                 histfunc='avg',
                 height=400)
    
    st.plotly_chart(fig)
   
def bar_charts():
    data_canada = px.data.gapminder().query("country == 'Canada'")
    fig = px.bar(data_canada, x='year', y='pop')

    st.plotly_chart(fig)
   
def pie():
    df = px.data.tips()
    fig = px.pie(df, values='tip', names='day', color='day',
                 color_discrete_map={
 'Thur':'lightcyan',
                                     'Fri':'cyan',
                                     'Sat':'royalblue',
                                     'Sun':'darkblue'})
    st.plotly_chart(fig)
   
def pulled_out():    
    labels = ['Oxygen','Hydrogen','Carbon_Dioxide','Nitrogen']
    values = [4500, 2500, 1053, 500]
    
    # pull is given as a fraction of the pie radius
    fig = go.Figure(data=[go.Pie(labels=labels, values=values, pull=[0, 0.2, 0, 0])])   
    st.plotly_chart(fig)

3. 实现双坐标图表实践

数据表通过Pandas直接读取(csv)数据为DataFrame,使用Streamlit的st.table直接显示数据表,使用plotly.graph_objects绘图。

@st.cache
def load_data():
    df = pd.read_csv('STAT202112.csv', encoding='gbk')
    df['年月'] = df['年月'].astype("str")    
    
    return df

def Double_coordinates():  
    df = load_data()

    st.markdown('#### 数据表展示')
    st.table(df)    

    st.markdown('#### 双坐标图')
    x = df["年月"]
    y1_1 = df['流失客户']
    y1_2=df['新客户']
    
    y2 = df["余额"]
    
    trace0_1 = go.Bar(x=x,y=y1_1,
                    marker=dict(color="red"),
                    opacity=0.5,
                   name="流失客户")

    trace0_2 = go.Bar(x=x,y=y1_2,
                    marker=dict(color="blue"),
                    opacity=0.5,
                   name="新客户")
    
    trace1 = go.Scatter(x=x,y=y2,
                        mode="lines",
                        name="余额",
                        # 【步骤一】:使用这个参数yaxis="y2",就是绘制双y轴图
                        yaxis="y2")
    
    data = [trace0_1,trace0_2,trace1]
    
    layout = go.Layout(title="客户发展趋势",
                       xaxis=dict(title="年月"),
                       yaxis=dict(title="客户数量"),
                       # 【步骤二】:给第二个y轴,添加标题,指定第二个y轴,在右侧。
                       yaxis2=dict(title="金额",overlaying="y",side="right"),
                       legend=dict(x=0.78,y=0.98,font=dict(size=12,color="black")))
    
    fig = go.Figure(data=data,layout=layout)
    
    st.plotly_chart(fig)

注:@st.cache 用于把数据加载到缓存,避免下次重复查询加载。

4. 总结

通过低代码Streamlit+Plotly的试用,感觉代码挺优雅,不用懂得任何前端技术,可以开发一个看起来还很美观的Web App。

Python数据分析师可以用更多时间专注数据表现上,通过图表为用户讲述数据的故事。