Plotly:如何制作多索引下拉选项? [英] Plotly: How to make a multiple index dropdown option?
问题描述
我有以下不同时间范围内具有相同索引号的数据
Time CallOI PutOI CallLTP PutLTP29500 下午 3:30 502725 554775 343.70 85.5029500 下午 3:15 568725 629700 357.15 81.7029500 2:59 下午 719350 689850 337.85 95.4529500 2:45 下午 786975 641575 360.00 108.3529500 下午 2:30 823500 626875 336.50 127.8029500 2:15 下午 812450 631800 308.55 143.0029500 下午 2:00 974700 617750 389.80 120.0029500 1:45 下午 1072675 547100 262.55 186.8529500 下午 1:30 1272300 469600 206.85 232.0029600 下午 3:30 502725 554775 343.70 85.5029600 下午 3:15 568725 629700 357.15 81.7029600 2:59 下午 719350 689850 337.85 95.4529600 2:45 下午 786975 641575 360.00 108.3529600 下午 2:30 823500 626875 336.50 127.8029600 2:15 下午 812450 631800 308.55 143.0029600 2:00 PM 974700 617750 389.80 120.0029600 1:45 下午 1072675 547100 262.55 186.8529600 下午 1:30 1272300 469600 206.85 232.0029700 下午 3:30 502725 554775 343.70 85.5029700 下午 3:15 568725 629700 357.15 81.7029700 2:59 下午 719350 689850 337.85 95.4529700 2:45 下午 786975 641575 360.00 108.3529700 下午 2:30 823500 626875 336.50 127.8029700 2:15 下午 812450 631800 308.55 143.0029700 下午 2:00 974700 617750 389.80 120.0029700 1:45 下午 1072675 547100 262.55 186.8529700 下午 1:30 1272300 469600 206.85 232.00
使用下面的代码我制作了图表:
subfig = make_subplots(specs=[[{secondary_y": True}]])# 用 px.line 创建两个独立的图形,每个图形都包含来自多列的数据fig = px.line(df,x='Time', y='Call OI')fig2 = px.line(df,x='Time', y='Call LTP')fig2.update_traces(yaxis=y2")subfig.add_traces(fig.data + fig2.data)subfig.layout.xaxis.title=时间"subfig.layout.yaxis.title=OI";subfig.layout.yaxis2.type=日志";subfig.layout.yaxis2.title=价格"# 重新着色是必要的,否则来自 fig 和 fig2 的行将共享每种颜色# 例如线性-,对数- = 蓝色;Linear+, Log+ = red...我们不想要这个subfig.for_each_trace(lambda t: t.update(line=dict(color=t.marker.color)))subfig.show()
我想要选择不同索引的下拉菜单,并且图表数据会相应更改.例如,如果我从下拉列表 29600 中选择它只显示该索引号的数据,并且还有一种方法可以从左到右翻转 x 轴(时间).提前感谢您提供任何解决方案
Edit 2 - 使用链接数据集更新建议
为了使用
编辑 2 的完整代码
导入集合导入破折号将熊猫导入为 pdfrom dash.dependencies import 输出,输入从 dash.exceptions 导入防止更新从 jupyter_dash 导入 JupyterDash将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 dash.dependencies 导入输入、输出、状态、ClientsideFunction将 dash_bootstrap_components 导入为 dbc将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 plotly.subplots 导入 make_subplots导入 plotly.graph_objects as godfi = pd.read_clipboard(sep=',')df = dfi.copy()idx = list(df['执行价格'].unique())app = JupyterDash()app.layout = html.Div([dcc.Store(id='memory-output'),dcc.Dropdown(id='memory-countries', options=[{'value': x, 'label': x} for x in idx], multi=False, value=idx[0]),dcc.Dropdown(id='memory-field', options=[{'值':'默认','标签':'默认'},{'value': 'reverse', 'label': 'reverse'},], 值='默认'),html.div([dcc.Graph(id='memory-graph'),])])@app.callback(Output('memory-output', 'data'),[输入('内存国家','值')])def filter_countries(idx_selected):如果不是 idx_selected:# 返回初始加载/未选择国家/地区的所有行.返回(idx_selected)返回(idx_selected)@app.callback(Output('memory-graph', 'figure'),[输入('内存输出','数据'),输入('内存字段','值')])def on_data_set_graph(数据,字段):# 打印(数据)#全局dff如果数据为无:提高预防更新#图形设置fig = make_subplots(specs=[[{secondary_y": True}]])dff = df[df['执行价格']==数据]fig.add_trace(go.Scatter(x=dff.Time, y = dff['Call OI'], name = 'Call'), secondary_y=True)fig.add_trace(go.Scatter(x=dff.Time, y = dff['Call LTP'], name = 'Put'), secondary_y=False)# 翻转轴如果字段 != '默认':fig.update_layout(xaxis = dict(autorange='reversed'))返回(图)app.run_server(mode='inline', port = 8072, dev_tools_ui=True,dev_tools_hot_reload =True,threaded=True,debug=True)
编辑 - 更新了轴翻转的建议
我的最新建议基于
这是完整的代码:
导入集合导入破折号将熊猫导入为 pdfrom dash.dependencies import 输出,输入从 dash.exceptions 导入防止更新从 jupyter_dash 导入 JupyterDash将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 dash.dependencies 导入输入、输出、状态、ClientsideFunction将 dash_bootstrap_components 导入为 dbc将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 plotly.subplots 导入 make_subplots导入 plotly.graph_objects as godf = pd.DataFrame({'Time': {(29500, '3:30'): 'PM',(29500, '3:15'): '下午',(29500, '2:59'): '下午',(29500, '2:45'): '下午',(29500, '2:30'): '下午',(29500, '2:15'): '下午',(29500, '2:00'): '下午',(29500, '1:45'): '下午',(29500, '1:30'): '下午',(29600, '3:30'): '下午',(29600, '3:15'): '下午',(29600, '2:59'): '下午',(29600, '2:45'): '下午',(29600, '2:30'): '下午',(29600, '2:15'): '下午',(29600, '2:00'): '下午',(29600, '1:45'): '下午',(29600, '1:30'): '下午',(29700, '3:30'): '下午',(29700, '3:15'): '下午',(29700, '2:59'): '下午',(29700, '2:45'): '下午',(29700, '2:30'): '下午',(29700, '2:15'): '下午',(29700, '2:00'): '下午',(29700, '1:45'): '下午',(29700, '1:30'): '下午'},'CallOI': {(29500, '3:30'): 502725,(29500, '3:15'): 568725,(29500, '2:59'): 719350,(29500, '2:45'): 786975,(29500, '2:30'): 823500,(29500, '2:15'): 812450,(29500, '2:00'): 974700,(29500, '1:45'): 1072675,(29500, '1:30'): 1272300,(29600, '3:30'): 502725,(29600, '3:15'): 568725,(29600, '2:59'): 719350,(29600, '2:45'): 786975,(29600, '2:30'): 823500,(29600, '2:15'): 812450,(29600, '2:00'): 974700,(29600, '1:45'): 1000000,(29600, '1:30'): 1272300,(29700, '3:30'): 502725,(29700, '3:15'): 568725,(29700, '2:59'): 719350,(29700, '2:45'): 786975,(29700, '2:30'): 823500,(29700, '2:15'): 812450,(29700, '2:00'): 974700,(29700, '1:45'): 1172675,(29700, '1:30'): 1272300},'PutOI': {(29500, '3:30'): 554775,(29500, '3:15'): 629700,(29500, '2:59'): 689850,(29500, '2:45'): 641575,(29500, '2:30'): 626875,(29500, '2:15'): 631800,(29500, '2:00'): 617750,(29500, '1:45'): 547100,(29500, '1:30'): 469600,(29600, '3:30'): 554775,(29600, '3:15'): 629700,(29600, '2:59'): 689850,(29600, '2:45'): 641575,(29600, '2:30'): 626875,(29600, '2:15'): 631800,(29600, '2:00'): 617750,(29600, '1:45'): 547100,(29600, '1:30'): 469600,(29700, '3:30'): 554775,(29700, '3:15'): 629700,(29700, '2:59'): 689850,(29700, '2:45'): 641575,(29700, '2:30'): 626875,(29700, '2:15'): 631800,(29700, '2:00'): 617750,(29700, '1:45'): 547100,(29700, '1:30'): 469600},'CallLTP': {(29500, '3:30'): 343.7,(29500, '3:15'): 357.15,(29500, '2:59'): 337.85,(29500, '2:45'): 360.0,(29500, '2:30'): 336.5,(29500, '2:15'): 308.55,(29500, '2:00'): 389.8,(29500, '1:45'): 262.55,(29500, '1:30'): 206.85,(29600, '3:30'): 343.7,(29600, '3:15'): 357.15,(29600, '2:59'): 337.85,(29600, '2:45'): 360.0,(29600, '2:30'): 336.5,(29600, '2:15'): 308.55,(29600, '2:00'): 389.8,(29600, '1:45'): 262.55,(29600, '1:30'): 206.85,(29700, '3:30'): 343.7,(29700, '3:15'): 357.15,(29700, '2:59'): 337.85,(29700, '2:45'): 360.0,(29700, '2:30'): 336.5,(29700, '2:15'): 308.55,(29700, '2:00'): 389.8,(29700, '1:45'): 262.55,(29700, '1:30'): 206.85},'PutLTP': {(29500, '3:30'): 85.5,(29500, '3:15'): 81.7,(29500, '2:59'): 95.45,(29500, '2:45'): 108.35,(29500, '2:30'): 127.8,(29500, '2:15'): 143.0,(29500, '2:00'): 120.0,(29500, '1:45'): 186.85,(29500, '1:30'): 232.0,(29600, '3:30'): 85.5,(29600, '3:15'): 81.7,(29600, '2:59'): 95.45,(29600, '2:45'): 108.35,(29600, '2:30'): 127.8,(29600, '2:15'): 143.0,(29600, '2:00'): 120.0,(29600, '1:45'): 186.85,(29600, '1:30'): 232.0,(29700, '3:30'): 85.5,(29700, '3:15'): 81.7,(29700, '2:59'): 95.45,(29700, '2:45'): 108.35,(29700, '2:30'): 127.8,(29700, '2:15'): 143.0,(29700, '2:00'): 120.0,(29700, '1:45'): 186.85,(29700, '1:30'): 232.0}})df = df.reset_index()idx = list(df['level_0'].unique())app = JupyterDash()app.layout = html.Div([dcc.Store(id='memory-output'),dcc.Dropdown(id='memory-countries', options=[{'value': x, 'label': x} for x in idx], multi=False, value=idx[0]),dcc.Dropdown(id='memory-field', options=[{'值':'默认','标签':'默认'},{'value': 'reverse', 'label': 'reverse'},],值='默认'),html.div([dcc.Graph(id='memory-graph'),])])@app.callback(Output('memory-output', 'data'),[输入('内存国家','值')])def filter_countries(idx_selected):如果不是 idx_selected:# 返回初始加载/未选择国家/地区的所有行.返回(idx_selected)返回(idx_selected)@app.callback(Output('memory-graph', 'figure'),[输入('内存输出','数据'),输入('内存字段','值')])def on_data_set_graph(数据,字段):# 打印(数据)如果数据为无:提高预防更新#图形设置fig = make_subplots(specs=[[{secondary_y": True}]])dff = df[df['level_0']==数据]fig.add_trace(go.Scatter(x=dff.level_1, y = dff.CallOI, name = 'Call'), secondary_y=True)fig.add_trace(go.Scatter(x=dff.level_1, y = dff.PutOI, name = 'Put'), secondary_y=False)# 翻转轴如果字段 != '默认':fig.update_layout(xaxis = dict(autorange='reversed'))返回(图)app.run_server(mode='inline', port = 8072, dev_tools_ui=True,dev_tools_hot_reload =True,threaded=True,debug=True)
建议 1
您尚未指定如何使用您的数字.但假设它在 JupyterLab 中,我强烈推荐使用 JupyterDash.我发现这比 r-beginners 在
完整代码
将 numpy 导入为 np将熊猫导入为 pd导入 plotly.express 作为 px导入 plotly.graph_objects as go从 jupyter_dash 导入 JupyterDash将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html从 dash.dependencies 导入输入,输出从 plotly.subplots 导入 make_subplots从 dash.dependencies 导入输入、输出、状态# 数据df = pd.DataFrame({'Time': {(29500, '3:30'): 'PM',(29500, '3:15'): '下午',(29500, '2:59'): '下午',(29500, '2:45'): '下午',(29500, '2:30'): '下午',(29500, '2:15'): '下午',(29500, '2:00'): '下午',(29500, '1:45'): '下午',(29500, '1:30'): '下午',(29600, '3:30'): '下午',(29600, '3:15'): '下午',(29600, '2:59'): '下午',(29600, '2:45'): '下午',(29600, '2:30'): '下午',(29600, '2:15'): '下午',(29600, '2:00'): '下午',(29600, '1:45'): '下午',(29600, '1:30'): '下午',(29700, '3:30'): '下午',(29700, '3:15'): '下午',(29700, '2:59'): '下午',(29700, '2:45'): '下午',(29700, '2:30'): '下午',(29700, '2:15'): '下午',(29700, '2:00'): '下午',(29700, '1:45'): '下午',(29700, '1:30'): '下午'},'CallOI': {(29500, '3:30'): 502725,(29500, '3:15'): 568725,(29500, '2:59'): 719350,(29500, '2:45'): 786975,(29500, '2:30'): 823500,(29500, '2:15'): 812450,(29500, '2:00'): 974700,(29500, '1:45'): 1072675,(29500, '1:30'): 1272300,(29600, '3:30'): 502725,(29600, '3:15'): 568725,(29600, '2:59'): 719350,(29600, '2:45'): 786975,(29600, '2:30'): 823500,(29600, '2:15'): 812450,(29600, '2:00'): 974700,(29600, '1:45'): 1000000,(29600, '1:30'): 1272300,(29700, '3:30'): 502725,(29700, '3:15'): 568725,(29700, '2:59'): 719350,(29700, '2:45'): 786975,(29700, '2:30'): 823500,(29700, '2:15'): 812450,(29700, '2:00'): 974700,(29700, '1:45'): 1172675,(29700, '1:30'): 1272300},'PutOI': {(29500, '3:30'): 554775,(29500, '3:15'): 629700,(29500, '2:59'): 689850,(29500, '2:45'): 641575,(29500, '2:30'): 626875,(29500, '2:15'): 631800,(29500, '2:00'): 617750,(29500, '1:45'): 547100,(29500, '1:30'): 469600,(29600, '3:30'): 554775,(29600, '3:15'): 629700,(29600, '2:59'): 689850,(29600, '2:45'): 641575,(29600, '2:30'): 626875,(29600, '2:15'): 631800,(29600, '2:00'): 617750,(29600, '1:45'): 547100,(29600, '1:30'): 469600,(29700, '3:30'): 554775,(29700, '3:15'): 629700,(29700, '2:59'): 689850,(29700, '2:45'): 641575,(29700, '2:30'): 626875,(29700, '2:15'): 631800,(29700, '2:00'): 617750,(29700, '1:45'): 547100,(29700, '1:30'): 469600},'CallLTP': {(29500, '3:30'): 343.7,(29500, '3:15'): 357.15,(29500, '2:59'): 337.85,(29500, '2:45'): 360.0,(29500, '2:30'): 336.5,(29500, '2:15'): 308.55,(29500, '2:00'): 389.8,(29500, '1:45'): 262.55,(29500, '1:30'): 206.85,(29600, '3:30'): 343.7,(29600, '3:15'): 357.15,(29600, '2:59'): 337.85,(29600, '2:45'): 360.0,(29600, '2:30'): 336.5,(29600, '2:15'): 308.55,(29600, '2:00'): 389.8,(29600, '1:45'): 262.55,(29600, '1:30'): 206.85,(29700, '3:30'): 343.7,(29700, '3:15'): 357.15,(29700, '2:59'): 337.85,(29700, '2:45'): 360.0,(29700, '2:30'): 336.5,(29700, '2:15'): 308.55,(29700, '2:00'): 389.8,(29700, '1:45'): 262.55,(29700, '1:30'): 206.85},'PutLTP': {(29500, '3:30'): 85.5,(29500, '3:15'): 81.7,(29500, '2:59'): 95.45,(29500, '2:45'): 108.35,(29500, '2:30'): 127.8,(29500, '2:15'): 143.0,(29500, '2:00'): 120.0,(29500, '1:45'): 186.85,(29500, '1:30'): 232.0,(29600, '3:30'): 85.5,(29600, '3:15'): 81.7,(29600, '2:59'): 95.45,(29600, '2:45'): 108.35,(29600, '2:30'): 127.8,(29600, '2:15'): 143.0,(29600, '2:00'): 120.0,(29600, '1:45'): 186.85,(29600, '1:30'): 232.0,(29700, '3:30'): 85.5,(29700, '3:15'): 81.7,(29700, '2:59'): 95.45,(29700, '2:45'): 108.35,(29700, '2:30'): 127.8,(29700, '2:15'): 143.0,(29700, '2:00'): 120.0,(29700, '1:45'): 186.85,(29700, '1:30'): 232.0}})df = df.reset_index()external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']app = JupyterDash(__name__, external_stylesheets=external_stylesheets)# 下拉选项标准 = 列表(df['level_0'].unique())options = [{'label': i, 'value': i} for i in conditions]选项.append# 应用布局app.layout = html.Div([html.div([html.div([dcc.Dropdown(id='linedropdown',选项=选项,value=options[0]['value'],),],),],className='row'),html.div([html.div([dcc.Graph(id='linechart'),],),],),])@app.callback([输出('折线图','图形')],[输入('linedropdown','值')])def update_graph(linedropdown):# 使用 linedropdown 选择dff = df[df['level_0']==linedropdown]# 创建带有辅助 y 轴的图形fig = make_subplots(specs=[[{secondary_y": True}]])# 添加跟踪 1fig.add_trace(go.Scatter(x=dff['level_1'], y=dff['CallOI'], name="Call OI"),secondary_y=真,)# 添加跟踪 2fig.add_trace(go.Scatter(x=dff['level_1'], y=dff['CallLTP'], name="Call LTP"),secondary_y=假,)fig.update_layout(title = 'Index:' + str(linedropdown))返回([图])# 运行应用程序并在笔记本中内联显示结果app.run_server(mode='inline', port = 8040, dev_tools_ui=True, debug=True,dev_tools_hot_reload =真,线程=真)
I have data with same index number for different timeframe as below
Time CallOI PutOI CallLTP PutLTP
29500 3:30 PM 502725 554775 343.70 85.50
29500 3:15 PM 568725 629700 357.15 81.70
29500 2:59 PM 719350 689850 337.85 95.45
29500 2:45 PM 786975 641575 360.00 108.35
29500 2:30 PM 823500 626875 336.50 127.80
29500 2:15 PM 812450 631800 308.55 143.00
29500 2:00 PM 974700 617750 389.80 120.00
29500 1:45 PM 1072675 547100 262.55 186.85
29500 1:30 PM 1272300 469600 206.85 232.00
29600 3:30 PM 502725 554775 343.70 85.50
29600 3:15 PM 568725 629700 357.15 81.70
29600 2:59 PM 719350 689850 337.85 95.45
29600 2:45 PM 786975 641575 360.00 108.35
29600 2:30 PM 823500 626875 336.50 127.80
29600 2:15 PM 812450 631800 308.55 143.00
29600 2:00 PM 974700 617750 389.80 120.00
29600 1:45 PM 1072675 547100 262.55 186.85
29600 1:30 PM 1272300 469600 206.85 232.00
29700 3:30 PM 502725 554775 343.70 85.50
29700 3:15 PM 568725 629700 357.15 81.70
29700 2:59 PM 719350 689850 337.85 95.45
29700 2:45 PM 786975 641575 360.00 108.35
29700 2:30 PM 823500 626875 336.50 127.80
29700 2:15 PM 812450 631800 308.55 143.00
29700 2:00 PM 974700 617750 389.80 120.00
29700 1:45 PM 1072675 547100 262.55 186.85
29700 1:30 PM 1272300 469600 206.85 232.00
using below code i have made chart :
subfig = make_subplots(specs=[[{"secondary_y": True}]])
# create two independent figures with px.line each containing data from multiple columns
fig = px.line(df,x='Time', y='Call OI')
fig2 = px.line(df,x='Time', y='Call LTP')
fig2.update_traces(yaxis="y2")
subfig.add_traces(fig.data + fig2.data)
subfig.layout.xaxis.title="Time"
subfig.layout.yaxis.title="OI"
subfig.layout.yaxis2.type="log"
subfig.layout.yaxis2.title="Price"
# recoloring is necessary otherwise lines from fig und fig2 would share each color
# e.g. Linear-, Log- = blue; Linear+, Log+ = red... we don't want this
subfig.for_each_trace(lambda t: t.update(line=dict(color=t.marker.color)))
subfig.show()
I want dropdown menu which selects different index and the chart data changes accordingly. example if i select from drop down 29600 it shows only data for that index number and also is there a way to flip x axis (time) from left to right. Thanks in advance for any solutions
Edit 2 - Updated suggestion with linked dataset
In order to use the full dataset provided in the link, just download that content as a csv file, open it and copy the contents, and then run the code below to get the next figure. The data is picked up using dfi = pd.read_clipboard(sep=',')
. There is really no need to bother with setting 'Strike Price
as index. Please note that the dataset has a lot of 0
values, but selecting, for example, 26100
will at least produce a meaningful output:
Complete code for edit 2
import collections
import dash
import pandas as pd
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from plotly.subplots import make_subplots
import plotly.graph_objects as go
dfi = pd.read_clipboard(sep=',')
df = dfi.copy()
idx = list(df['Strike Price'].unique())
app = JupyterDash()
app.layout = html.Div([
dcc.Store(id='memory-output'),
dcc.Dropdown(id='memory-countries', options=[
{'value': x, 'label': x} for x in idx
], multi=False, value=idx[0]),
dcc.Dropdown(id='memory-field', options=[
{'value': 'default', 'label': 'default'},
{'value': 'reverse', 'label': 'reverse'},
], value='default'),
html.Div([
dcc.Graph(id='memory-graph'),
])
])
@app.callback(Output('memory-output', 'data'),
[Input('memory-countries', 'value')])
def filter_countries(idx_selected):
if not idx_selected:
# Return all the rows on initial load/no country selected.
return(idx_selected)
return(idx_selected)
@app.callback(Output('memory-graph', 'figure'),
[Input('memory-output', 'data'),
Input('memory-field', 'value')])
def on_data_set_graph(data, field):
# print(data)
# global dff
if data is None:
raise PreventUpdate
# figure setup
fig = make_subplots(specs=[[{"secondary_y": True}]])
dff = df[df['Strike Price']==data]
fig.add_trace(go.Scatter(x=dff.Time, y = dff['Call OI'], name = 'Call'), secondary_y=True)
fig.add_trace(go.Scatter(x=dff.Time, y = dff['Call LTP'], name = 'Put'), secondary_y=False)
# flip axis
if field != 'default':
fig.update_layout(xaxis = dict(autorange='reversed'))
return(fig)
app.run_server(mode='inline', port = 8072, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True, debug=True)
Edit - Updated suggestion with axis flipping
My latest suggestion builds on an example under the section Share data between callbacks
from dcc.Store and makes the necessary adjustments to work for your use case. I've also incorporated a functionality to flip your x-axis values using: fig.update_layout(xaxis = dict(autorange='reversed'))
Here's the result:
And here's the complete code:
import collections
import dash
import pandas as pd
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from plotly.subplots import make_subplots
import plotly.graph_objects as go
df = pd.DataFrame({'Time': {(29500, '3:30'): 'PM',
(29500, '3:15'): 'PM',
(29500, '2:59'): 'PM',
(29500, '2:45'): 'PM',
(29500, '2:30'): 'PM',
(29500, '2:15'): 'PM',
(29500, '2:00'): 'PM',
(29500, '1:45'): 'PM',
(29500, '1:30'): 'PM',
(29600, '3:30'): 'PM',
(29600, '3:15'): 'PM',
(29600, '2:59'): 'PM',
(29600, '2:45'): 'PM',
(29600, '2:30'): 'PM',
(29600, '2:15'): 'PM',
(29600, '2:00'): 'PM',
(29600, '1:45'): 'PM',
(29600, '1:30'): 'PM',
(29700, '3:30'): 'PM',
(29700, '3:15'): 'PM',
(29700, '2:59'): 'PM',
(29700, '2:45'): 'PM',
(29700, '2:30'): 'PM',
(29700, '2:15'): 'PM',
(29700, '2:00'): 'PM',
(29700, '1:45'): 'PM',
(29700, '1:30'): 'PM'},
'CallOI': {(29500, '3:30'): 502725,
(29500, '3:15'): 568725,
(29500, '2:59'): 719350,
(29500, '2:45'): 786975,
(29500, '2:30'): 823500,
(29500, '2:15'): 812450,
(29500, '2:00'): 974700,
(29500, '1:45'): 1072675,
(29500, '1:30'): 1272300,
(29600, '3:30'): 502725,
(29600, '3:15'): 568725,
(29600, '2:59'): 719350,
(29600, '2:45'): 786975,
(29600, '2:30'): 823500,
(29600, '2:15'): 812450,
(29600, '2:00'): 974700,
(29600, '1:45'): 1000000,
(29600, '1:30'): 1272300,
(29700, '3:30'): 502725,
(29700, '3:15'): 568725,
(29700, '2:59'): 719350,
(29700, '2:45'): 786975,
(29700, '2:30'): 823500,
(29700, '2:15'): 812450,
(29700, '2:00'): 974700,
(29700, '1:45'): 1172675,
(29700, '1:30'): 1272300},
'PutOI': {(29500, '3:30'): 554775,
(29500, '3:15'): 629700,
(29500, '2:59'): 689850,
(29500, '2:45'): 641575,
(29500, '2:30'): 626875,
(29500, '2:15'): 631800,
(29500, '2:00'): 617750,
(29500, '1:45'): 547100,
(29500, '1:30'): 469600,
(29600, '3:30'): 554775,
(29600, '3:15'): 629700,
(29600, '2:59'): 689850,
(29600, '2:45'): 641575,
(29600, '2:30'): 626875,
(29600, '2:15'): 631800,
(29600, '2:00'): 617750,
(29600, '1:45'): 547100,
(29600, '1:30'): 469600,
(29700, '3:30'): 554775,
(29700, '3:15'): 629700,
(29700, '2:59'): 689850,
(29700, '2:45'): 641575,
(29700, '2:30'): 626875,
(29700, '2:15'): 631800,
(29700, '2:00'): 617750,
(29700, '1:45'): 547100,
(29700, '1:30'): 469600},
'CallLTP': {(29500, '3:30'): 343.7,
(29500, '3:15'): 357.15,
(29500, '2:59'): 337.85,
(29500, '2:45'): 360.0,
(29500, '2:30'): 336.5,
(29500, '2:15'): 308.55,
(29500, '2:00'): 389.8,
(29500, '1:45'): 262.55,
(29500, '1:30'): 206.85,
(29600, '3:30'): 343.7,
(29600, '3:15'): 357.15,
(29600, '2:59'): 337.85,
(29600, '2:45'): 360.0,
(29600, '2:30'): 336.5,
(29600, '2:15'): 308.55,
(29600, '2:00'): 389.8,
(29600, '1:45'): 262.55,
(29600, '1:30'): 206.85,
(29700, '3:30'): 343.7,
(29700, '3:15'): 357.15,
(29700, '2:59'): 337.85,
(29700, '2:45'): 360.0,
(29700, '2:30'): 336.5,
(29700, '2:15'): 308.55,
(29700, '2:00'): 389.8,
(29700, '1:45'): 262.55,
(29700, '1:30'): 206.85},
'PutLTP': {(29500, '3:30'): 85.5,
(29500, '3:15'): 81.7,
(29500, '2:59'): 95.45,
(29500, '2:45'): 108.35,
(29500, '2:30'): 127.8,
(29500, '2:15'): 143.0,
(29500, '2:00'): 120.0,
(29500, '1:45'): 186.85,
(29500, '1:30'): 232.0,
(29600, '3:30'): 85.5,
(29600, '3:15'): 81.7,
(29600, '2:59'): 95.45,
(29600, '2:45'): 108.35,
(29600, '2:30'): 127.8,
(29600, '2:15'): 143.0,
(29600, '2:00'): 120.0,
(29600, '1:45'): 186.85,
(29600, '1:30'): 232.0,
(29700, '3:30'): 85.5,
(29700, '3:15'): 81.7,
(29700, '2:59'): 95.45,
(29700, '2:45'): 108.35,
(29700, '2:30'): 127.8,
(29700, '2:15'): 143.0,
(29700, '2:00'): 120.0,
(29700, '1:45'): 186.85,
(29700, '1:30'): 232.0}})
df = df.reset_index()
idx = list(df['level_0'].unique())
app = JupyterDash()
app.layout = html.Div([
dcc.Store(id='memory-output'),
dcc.Dropdown(id='memory-countries', options=[
{'value': x, 'label': x} for x in idx
], multi=False, value=idx[0]),
dcc.Dropdown(id='memory-field', options=[
{'value': 'default', 'label': 'default'},
{'value': 'reverse', 'label': 'reverse'},
], value='default'),
html.Div([
dcc.Graph(id='memory-graph'),
])
])
@app.callback(Output('memory-output', 'data'),
[Input('memory-countries', 'value')])
def filter_countries(idx_selected):
if not idx_selected:
# Return all the rows on initial load/no country selected.
return(idx_selected)
return(idx_selected)
@app.callback(Output('memory-graph', 'figure'),
[Input('memory-output', 'data'),
Input('memory-field', 'value')])
def on_data_set_graph(data, field):
# print(data)
if data is None:
raise PreventUpdate
# figure setup
fig = make_subplots(specs=[[{"secondary_y": True}]])
dff = df[df['level_0']==data]
fig.add_trace(go.Scatter(x=dff.level_1, y = dff.CallOI, name = 'Call'), secondary_y=True)
fig.add_trace(go.Scatter(x=dff.level_1, y = dff.PutOI, name = 'Put'), secondary_y=False)
# flip axis
if field != 'default':
fig.update_layout(xaxis = dict(autorange='reversed'))
return(fig)
app.run_server(mode='inline', port = 8072, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True, debug=True)
Suggestion 1
You haven't specified how you're using your figures. But assuming it's in JupyterLab, I would higlhy reccommend using JupyterDash. I find that much more felxible than incorporating dropdown features directly in the figure as r-beginners pointed to in the link in the comments.
The code snippet below will let you select which index to show data from in the followin app which is set to produce the figure 'inline'
which means in the notebook itself. If you're interested in using an approach like this, I can see if I can implement a button to flip the x-axis as well.
App:
Complete code
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from plotly.subplots import make_subplots
from dash.dependencies import Input, Output, State
# data
df = pd.DataFrame({'Time': {(29500, '3:30'): 'PM',
(29500, '3:15'): 'PM',
(29500, '2:59'): 'PM',
(29500, '2:45'): 'PM',
(29500, '2:30'): 'PM',
(29500, '2:15'): 'PM',
(29500, '2:00'): 'PM',
(29500, '1:45'): 'PM',
(29500, '1:30'): 'PM',
(29600, '3:30'): 'PM',
(29600, '3:15'): 'PM',
(29600, '2:59'): 'PM',
(29600, '2:45'): 'PM',
(29600, '2:30'): 'PM',
(29600, '2:15'): 'PM',
(29600, '2:00'): 'PM',
(29600, '1:45'): 'PM',
(29600, '1:30'): 'PM',
(29700, '3:30'): 'PM',
(29700, '3:15'): 'PM',
(29700, '2:59'): 'PM',
(29700, '2:45'): 'PM',
(29700, '2:30'): 'PM',
(29700, '2:15'): 'PM',
(29700, '2:00'): 'PM',
(29700, '1:45'): 'PM',
(29700, '1:30'): 'PM'},
'CallOI': {(29500, '3:30'): 502725,
(29500, '3:15'): 568725,
(29500, '2:59'): 719350,
(29500, '2:45'): 786975,
(29500, '2:30'): 823500,
(29500, '2:15'): 812450,
(29500, '2:00'): 974700,
(29500, '1:45'): 1072675,
(29500, '1:30'): 1272300,
(29600, '3:30'): 502725,
(29600, '3:15'): 568725,
(29600, '2:59'): 719350,
(29600, '2:45'): 786975,
(29600, '2:30'): 823500,
(29600, '2:15'): 812450,
(29600, '2:00'): 974700,
(29600, '1:45'): 1000000,
(29600, '1:30'): 1272300,
(29700, '3:30'): 502725,
(29700, '3:15'): 568725,
(29700, '2:59'): 719350,
(29700, '2:45'): 786975,
(29700, '2:30'): 823500,
(29700, '2:15'): 812450,
(29700, '2:00'): 974700,
(29700, '1:45'): 1172675,
(29700, '1:30'): 1272300},
'PutOI': {(29500, '3:30'): 554775,
(29500, '3:15'): 629700,
(29500, '2:59'): 689850,
(29500, '2:45'): 641575,
(29500, '2:30'): 626875,
(29500, '2:15'): 631800,
(29500, '2:00'): 617750,
(29500, '1:45'): 547100,
(29500, '1:30'): 469600,
(29600, '3:30'): 554775,
(29600, '3:15'): 629700,
(29600, '2:59'): 689850,
(29600, '2:45'): 641575,
(29600, '2:30'): 626875,
(29600, '2:15'): 631800,
(29600, '2:00'): 617750,
(29600, '1:45'): 547100,
(29600, '1:30'): 469600,
(29700, '3:30'): 554775,
(29700, '3:15'): 629700,
(29700, '2:59'): 689850,
(29700, '2:45'): 641575,
(29700, '2:30'): 626875,
(29700, '2:15'): 631800,
(29700, '2:00'): 617750,
(29700, '1:45'): 547100,
(29700, '1:30'): 469600},
'CallLTP': {(29500, '3:30'): 343.7,
(29500, '3:15'): 357.15,
(29500, '2:59'): 337.85,
(29500, '2:45'): 360.0,
(29500, '2:30'): 336.5,
(29500, '2:15'): 308.55,
(29500, '2:00'): 389.8,
(29500, '1:45'): 262.55,
(29500, '1:30'): 206.85,
(29600, '3:30'): 343.7,
(29600, '3:15'): 357.15,
(29600, '2:59'): 337.85,
(29600, '2:45'): 360.0,
(29600, '2:30'): 336.5,
(29600, '2:15'): 308.55,
(29600, '2:00'): 389.8,
(29600, '1:45'): 262.55,
(29600, '1:30'): 206.85,
(29700, '3:30'): 343.7,
(29700, '3:15'): 357.15,
(29700, '2:59'): 337.85,
(29700, '2:45'): 360.0,
(29700, '2:30'): 336.5,
(29700, '2:15'): 308.55,
(29700, '2:00'): 389.8,
(29700, '1:45'): 262.55,
(29700, '1:30'): 206.85},
'PutLTP': {(29500, '3:30'): 85.5,
(29500, '3:15'): 81.7,
(29500, '2:59'): 95.45,
(29500, '2:45'): 108.35,
(29500, '2:30'): 127.8,
(29500, '2:15'): 143.0,
(29500, '2:00'): 120.0,
(29500, '1:45'): 186.85,
(29500, '1:30'): 232.0,
(29600, '3:30'): 85.5,
(29600, '3:15'): 81.7,
(29600, '2:59'): 95.45,
(29600, '2:45'): 108.35,
(29600, '2:30'): 127.8,
(29600, '2:15'): 143.0,
(29600, '2:00'): 120.0,
(29600, '1:45'): 186.85,
(29600, '1:30'): 232.0,
(29700, '3:30'): 85.5,
(29700, '3:15'): 81.7,
(29700, '2:59'): 95.45,
(29700, '2:45'): 108.35,
(29700, '2:30'): 127.8,
(29700, '2:15'): 143.0,
(29700, '2:00'): 120.0,
(29700, '1:45'): 186.85,
(29700, '1:30'): 232.0}})
df = df.reset_index()
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)
# options for dropdown
criteria = list(df['level_0'].unique())
options = [{'label': i, 'value': i} for i in criteria]
options.append
# app layout
app.layout = html.Div([
html.Div([
html.Div([
dcc.Dropdown(id='linedropdown',
options=options,
value=options[0]['value'],),
],
),
],className='row'),
html.Div([
html.Div([
dcc.Graph(id='linechart'),
],
),
],
),
])
@app.callback(
[Output('linechart', 'figure')],
[Input('linedropdown', 'value')]
)
def update_graph(linedropdown):
# selection using linedropdown
dff = df[df['level_0']==linedropdown]
# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
# Add trace 1
fig.add_trace(
go.Scatter(x=dff['level_1'], y=dff['CallOI'], name="Call OI"),
secondary_y=True,
)
# Add trace 2
fig.add_trace(
go.Scatter(x=dff['level_1'], y=dff['CallLTP'], name="Call LTP"),
secondary_y=False,
)
fig.update_layout(title = 'Index: ' + str(linedropdown))
return ([fig])
# Run app and display result inline in the notebook
app.run_server(mode='inline', port = 8040, dev_tools_ui=True, debug=True,
dev_tools_hot_reload =True, threaded=True)
这篇关于Plotly:如何制作多索引下拉选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!