Fork me on GitHub

plotly-express-7-Dash利用滑动条实现数据选择

本文中介绍的是Dash如何利用滑动条实现数据选择,同时自动更新可视化的图形

  • 利用Slider实现
  • 利用RangeSlider实现
  • 利用px库实现RangeSlider

利用Slider实现

Slider的特点是:一端是固定的,只能够移动一个端点

demo

官网上的demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import dash
import dash_html_components as html
import dash_core_components as dcc

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

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Slider(
id='my-slider',
min=0,
max=20,
step=0.5,
value=10,
),
html.Div(id='slider-output-container')
])


@app.callback(
dash.dependencies.Output('slider-output-container', 'children'),
[dash.dependencies.Input('my-slider', 'value')])
def update_output(value):
return 'You have selected "{}"'.format(value)


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

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import plotly_express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

import pandas as pd

df = px.data.gapminder() # 使用px内置的数据

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
html.H1("Select Data with Slider", style={"text-align":"center","color":"blue"}),
dcc.Graph(id="graph-with-slider"),
dcc.Slider(
id = "year-slider",
min = df["year"].min(), max = df["year"].max(),value = df["year"].min(), # 范围和初始值
marks = {str(year):str(year) for year in df["year"].unique()}, # 滑动条下每个年份数字,改成字符型数据
step = None # 步长
)
])

@app.callback(
Output("graph-with-slider","figure"), # 输出与输入,和上面的名称一一对应
[Input("year-slider","value")]
)

def update_figure(selected_year): # 生成画图需要的数据
filtered_df = df[df.year == selected_year] # 将指定年份的数据选择出来
traces = []
for i in filtered_df.continent.unique(): # continent 属于哪个洲
df_by_continent = filtered_df[filtered_df["continent"] == i] # 将已过滤年份的数据指定大洲再选择
traces.append(dict(
x = df_by_continent["gdpPercap"], # 横纵坐标
y = df_by_continent["lifeExp"],
text = df_by_continent["country"], # 显示国家
mode = "markers", # 使用圆点
opacity = 0.7, # 透明度设置
marker = { # 上面marker的属性设置:大小和外围颜色
"size":15, # 圆点大小
"line":{"width":0.7, "color":"white"}
},
name = i # 左上角的图例信息,将trace改成实际的名字
))
return { # 返回的内容
"data":traces, # 数据必须是列表形式,列表中的元素是字典的键值对
"layout":dict(
xaxis = {"type":"log", # x轴的数据以对数log的形式展现
"title":"GDP for Per Captial",
"range": [2.3, 4.8]}, # 范围
yaxis = {"title":"Life Expectancy", "range":[20,90]},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10}, # 定义图片的上下左右
legend = {"x":0,"y":1},
hovermode = "closest", # 只显示最近点的数据
transition = {"duration":500},
)
}

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

参数解释

下面是各个组件中重要参数的详细解释,辅助理解

利用RangeSlider实现

RangeSlider的特点是:两个端点都是可以移动的

demo

这里是官网上的demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import dash
import dash_html_components as html
import dash_core_components as dcc

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

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.RangeSlider(
id='my-range-slider',
min=0,
max=20,
step=0.5,
value=[5,10]
),
html.Div(id='output-container-range-slider')
])


@app.callback(
Output('output-container-range-slider', 'children'),
[Input('my-range-slider', 'value')])

def update_output(value):
# return value[0] + value[1]
return 'You have selected "{}"'.format(value)

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

实例

通过RangeSlider得到的数据是列表形式,可以通过索引取出每个数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import dash
import dash_html_components as html
import dash_core_components as dcc

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
html.H1("Select Data with RangeSlider", style={"text-align":"center","color":"blue"}),
dcc.Graph(id="graph-with-rangeslider"),
dcc.RangeSlider(
id = "year-rangeslider",
min = df["year"].min(),
max = df["year"].max(),
value = [1952, 1957], # 范围和初始值
marks = {str(year):str(year) for year in df["year"].unique()}, # 滑动条下每个年份数字,改成字符型数据
step = None # 步长
),
# html.Div(id='output-container-range-slider')
])


@app.callback(
Output("graph-with-rangeslider","figure"), # 输出与输入,和上面的名称一一对应
# Output('output-container-range-slider', 'children'),
[Input("year-rangeslider","value")]
)


def update_figure(selected_year): # 生成画图需要的数据

# 通过索引将指定年份的数据选择出来,再通过concat函数进行合并,得到完整的、用于处理的数据
filtered_df0 = df[df.year == selected_year[0]]
filtered_df1 = df[df.year == selected_year[1]]
filtered_df = pd.concat([filtered_df0,filtered_df1])
# return px.scatter(filtered_df,x="gdpPercap",y="lifeExp",log_x=True,hover_data=["continent","country"],color="country")

traces = []

for i in filtered_df.continent.unique(): # continent 属于哪个洲
df_by_continent = filtered_df[filtered_df["continent"] == i] # 将已过滤年份的数据指定大洲再选择
traces.append(dict(
x = df_by_continent["gdpPercap"], # 横纵坐标
y = df_by_continent["lifeExp"],
text = df_by_continent["country"], # 显示国家
mode = "markers", # 使用圆点
opacity = 0.7, # 透明度设置
marker = { # 上面marker的属性设置:大小和外围颜色
"size":15, # 圆点大小
"line":{"width":0.7, "color":"white"}
},
name = i # 左上角的图例信息,将trace改成实际的名字
))

return { # 返回的内容
"data":traces, # 数据必须是列表形式,列表中的元素是字典的键值对
"layout":dict(
xaxis = {"type":"log", # x轴的数据以对数log的形式展现
"title":"GDP for Per Captial",
"range": [2.3, 4.8]}, # 范围
yaxis = {"title":"Life Expectancy", "range":[20,90]},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10}, # 定义图片的上下左右
legend = {"x":0,"y":1},
hovermode = "closest", # 只显示最近点的数据
transition = {"duration":500},
)
}

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

效果图如下:

利用px库实现RangeSlider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import dash
import dash_html_components as html
import dash_core_components as dcc

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
html.H1("Select Data with RangeSlider", style={"text-align":"center","color":"blue"}),
dcc.Graph(id="graph-with-rangeslider"),
dcc.RangeSlider(
id = "year-rangeslider",
min = df["year"].min(),
max = df["year"].max(),
value = [1952, 1957], # 范围和初始值
marks = {str(year):str(year) for year in df["year"].unique()}, # 滑动条下每个年份数字,改成字符型数据
step = None # 步长
),
# html.Div(id='output-container-range-slider')
])


@app.callback(
Output("graph-with-rangeslider","figure"), # 输出与输入,和上面的名称一一对应
# Output('output-container-range-slider', 'children'),
[Input("year-rangeslider","value")]
)


def update_figure(selected_year): # 生成画图需要的数据

filtered_df0 = df[df.year == selected_year[0]] # 将指定年份的数据选择出来
filtered_df1 = df[df.year == selected_year[1]]
filtered_df = pd.concat([filtered_df0,filtered_df1])
return px.scatter(filtered_df,x="gdpPercap",y="lifeExp",log_x=True,hover_data=["continent","country"],color="continent") # 使用对数,显示多个数据hover_data属性

本文标题:plotly-express-7-Dash利用滑动条实现数据选择

发布时间:2020年06月26日 - 20:06

原始链接:http://www.renpeter.cn/2020/06/26/plotly-express-7-Dash%E5%88%A9%E7%94%A8%E6%BB%91%E5%8A%A8%E6%9D%A1%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E9%80%89%E6%8B%A9.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea