Python可视化数据库Dash

Dash 简介

Dash是一个用于构建Web应用程序的Python数据可视化库。它基于Python Web框架Flask以及Javascript绘图库Plotly.js和用于构建用户界面的Javascript库React.js,所以它非常适合用于构建后端基于Flask,前端数据可视化的Web网页。因为Dash应用程序可以在Web浏览器中显示,所以可以将这些Dash应用程序部署到服务器,通过URL共享。Dash应用程序由两部分组成,第一部分是布局(Layout),该部分描述了应用程序的设计样式,用来展示数据以及引导用户使用;第二部分描述了应用程序的交互性

下面展示一个Demo
###Demo简介
使用Dash数据可视化NBA2018-2019常规赛季得分榜前三十各项数据,查看球员得分折线图、球员得分条形图,来分析NBA各大球星的得分趋势,得分值集中范围,以及得分落差。查看得分命中率和三分命中率散点图,来分析各大球星的投篮能力,得分能力。

第一步,准备数据

虎扑官网爬取NBA常规赛得分榜前三十球员的相关数据(姓名、球队、得分、得分命中率、三分命中率、罚球命中率)
代码如下:

import requests
from lxml import etree

url = 'https://nba.hupu.com/stats/players'

response = requests.get(url).text
html = etree.HTML(response)

result = []

for i in range(2,32):
    cur = []
    # 姓名数据解析
    name = html.xpath("//table[@class='players_table']/tbody/tr[{}]/td[2]/a/text()".format(i))
    # 球队数据解析
    team = html.xpath("//table[@class='players_table']/tbody/tr[{}]/td[3]/a/text()".format(i))
    # 得分数据解析
    core = html.xpath("//table[@class='players_table']/tbody/tr[{}]/td[4]/text()".format(i))
    # 得分命中率数据解析
    shooting = html.xpath("//table[@class='players_table']/tbody/tr[{}]/td[6]/text()".format(i))
    # 三分命中率数据解析
    threeshooting = html.xpath("//table[@class='players_table']/tbody/tr[{}]/td[8]/text()".format(i))
    # 罚球命中率数据解析
    freeshooting = html.xpath("//table[@class='players_table']/tbody/tr[{}]/td[10]/text()".format(i))
    cur.append(name[0])
    cur.append(team[0])
    cur.append(core[0])
    cur.append(shooting[0])
    cur.append(threeshooting[0])
    cur.append(freeshooting[0])
    result.append(cur)

得到如下数据

players = [['詹姆斯-哈登', '火箭', '36.10', '44.2%', '36.8%', '87.9%'],
           ['保罗-乔治', '快船', '28.00', '43.8%', '38.6%', '83.9%'],
           ['扬尼斯-阿德托昆博', '雄鹿', '27.70', '57.8%', '25.6%', '72.9%'],
           ['乔尔-恩比德', '76人', '27.50', '48.4%', '30%', '80.4%'],
           ['斯蒂芬-库里', '勇士', '27.30', '47.2%', '43.7%', '91.6%'],
           ['德文-布克', '太阳', '26.60', '46.7%', '32.6%', '86.6%'],
           ['科怀-伦纳德', '快船', '26.60', '49.6%', '37.1%', '85.4%'],
           ['凯文-杜兰特', '篮网', '26.00', '52.1%', '35.3%', '88.5%'],
           ['达米安-利拉德', '开拓者', '25.80', '44.4%', '36.9%', '91.2%'],
           ['肯巴-沃克', '凯尔特人', '25.60', '43.4%', '35.6%', '84.4%'],
           ['布拉德利-比尔', '奇才', '25.60', '47.5%', '35.1%', '80.8%'],
           ['布雷克-格里芬', '活塞', '24.50', '46.2%', '36.2%', '75.3%'],
           ['卡尔-安东尼-唐斯', '森林狼', '24.40', '51.8%', '40%', '83.6%'],
           ['多诺万-米切尔', '爵士', '23.80', '43.2%', '36.2%', '80.6%'],
           ['凯里-欧文', '篮网', '23.80', '48.7%', '40.1%', '87.3%'],
           ['扎克-拉文', '公牛', '23.70', '46.7%', '37.4%', '83.2%'],
           ['拉塞尔-威斯布鲁克', '火箭', '22.90', '42.8%', '29%', '65.6%'],
           ['克莱-汤普森', '勇士', '21.50', '46.7%', '40.2%', '81.6%'],
           ['朱利叶斯-兰德尔', '尼克斯', '21.40', '52.4%', '34.4%', '73.1%'],
           ['拉马库斯-阿尔德里奇', '马刺', '21.30', '51.9%', '23.8%', '84.7%'],
           ['朱-霍勒迪', '鹈鹕', '21.20', '47.2%', '32.5%', '76.8%'],
           ['德马尔-德罗赞', '马刺', '21.20', '48.1%', '15.6%', '83%'],
           ['卢卡-东契奇', '独行侠', '21.20', '42.7%', '32.7%', '71.3%'],
           ['迈克-康利', '爵士', '21.10', '43.8%', '36.4%', '84.5%'],
           ['丹吉洛-拉塞尔', '勇士', '21.10', '43.4%', '36.9%', '78%'],
           ['CJ-麦科勒姆', '开拓者', '21.00', '45.9%', '37.5%', '82.8%'],
           ['尼古拉-武切维奇', '魔术', '20.80', '51.8%', '36.4%', '78.9%'],
           ['巴迪-希尔德', '国王', '20.70', '45.8%', '42.7%', '88.6%'],
           ['尼古拉-约基奇', '掘金', '20.10', '51.1%', '30.7%', '82.1%'],
           ['路易斯-威廉姆斯', '快船', '20.00', '42.5%', '36.1%', '87.6%']
           ]

第二步,对数据可视化后台代码编写

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
    # 指定图的id
    dcc.Graph(id = 'graph-with-slider'),
    # 定义滑块的各项属性
    dcc.Slider(
        id = 'class-slider',
        min = 1,
        max = 4,
        value = 2,
        marks = {'1':'得分条形图','2':'命中率条形图','3':'得分折线图','4':'三分命中率散点图'},
        step = None
    )
])
# 定义回调函数,使用‘@app.callback()'参数装饰器来装饰该回调函数,输出绑定图id,输入绑定滑块值
@app.callback(
    Output('graph-with-slider', 'figure'),
    [Input('class-slider','value')]
)
def update_output_div(input_value):
    # 当滑块滑至1时,即输入值为1,返回得分条形图
    if input_value == 1:
        fig1 = dict(
            data=[{'x': [i+1], 'y': [float(players[i][2])], 'type': 'bar', 'name': '{}'.format(players[i][0])} for i in range(len(players))],
            layout = dict(title = 'NBA2018-2019赛季常规赛得分榜前十各项数据比较')
            )
        return fig1
    # 当滑块滑至3,即输入值为3时,返回球员得分折线图
    if input_value == 3:
        x = []
        y = []
        for player in players:
            x.append(player[0])
            y.append(player[2])
        fig2 = dict(
            data=[
                {'x':x,'y':y,'type':'Scatter','name':'Core'}
                    ],
                    layout ={
            'title': '球员得分折线图'
        }
        )
        return fig2
    # 当滑块滑至2时,即输入值为2,返回命中率条形图
    if input_value == 2:
        fig3 = dict(
            data=[

                {'x':[players[i][0]],'y':[float(players[i][3][0:4])],'type':'bar','name':'{}'.format(players[i][0])}for i in range(len(players))


            ],
            layout=dict(title='球员命中率条形图')
        )
        return fig3
    # 当滑块滑至4时,即输入值为4,返回得分命中率与三命中率散点图
    if input_value==4:
        x = []
        y = []
        team = []
        for player in players:
            x.append(float(player[3][0:4]))
            if len(player[4])==5:
                y.append(float(player[4][0:3]))
            else:
                y.append(float(player[4][0:2]))
            team.append(player[1])
        fig4=dict(
            data = [
                go.Scatter(
                    x = [x[i]],
                    y = [y[i]],
                    text = team,
                    name = players[i][0],
                    mode='markers',
                    opacity=0.8,
                    marker=dict(size=15, line=dict(width=0.5, color='white'))
                )for i in range(len(players))
            ],
            layout=go.Layout(

                xaxis=dict(type='log', title='得分命中率'),
                yaxis=dict(title='三分命中率', range=[10, 50]),
                margin=dict(l=40, b=40, t=10, r=10),
                hovermode='closest',
        title = '球员得分命中率与三分命中率',
            )
            )


        return fig4
if __name__ == '__main__':
    # 开启服务,指定端口号为7000
    app.run_server(port=7000)

上述代码即定义一个dash应用程序,通过回调函数来控制不同图的展示

4,应用程序展示

当滑块滑至1时,得分条形图展示
得到下图Python可视化数据库Dash_第1张图片

当滑块滑至2时,命中率条形图展示
Python可视化数据库Dash_第2张图片

当滑块滑至3时,得分折线图展示
Python可视化数据库Dash_第3张图片

当滑块滑至4时,得分命中率与三分命中率散点图展示
Python可视化数据库Dash_第4张图片

你可能感兴趣的:(Python可视化数据库Dash)