如何在没有 jupyter 的情况下导出此交互式图以在浏览器中查看?
how can I export this interactive plot to view in a browser without jupyter?
我在python中有这个互动情节:
import ipywidgets as widgets
import plotly.graph_objects as go
from numpy import linspace
def leaf_plot(sense, spec):
fig = go.Figure()
x = linspace(0,1,101)
x[0] += 1e-16
x[-1] -= 1e-16
positive = sense*x/(sense*x + (1-spec)*(1-x))
#probability a person is infected, given a positive test result,
#P(p|pr) = P(pr|p)*P(p)/P(pr)
# = P(pr|p)*P(p)/(P(pr|p)*P(p) + P(pr|n)*P(n))
# = sense*P(p)/( sense*P(p) +(1-spec)*P(n))
negative = 1-spec*(1-x)/((1-sense)*x + spec*(1-x))
fig.add_trace(
go.Scatter(x=x, y = positive, name="Positive",marker=dict( color='red'))
)
fig.add_trace(
go.Scatter(x=x, y = negative,
name="Negative",
mode = 'lines+markers',
marker=dict( color='green'))
)
fig.update_xaxes(title_text = "Base Rate")
fig.update_yaxes(title_text = "Post-test Probability")
fig.show()
sense_ = widgets.FloatSlider(
value=0.5,
min=0,
max=1.0,
step=0.01,
description='Sensitivity:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='.2f',
)
spec_ = widgets.FloatSlider(
value=0.5,
min=0,
max=1.0,
step=0.01,
description='Specificity:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='.2f',
)
ui = widgets.VBox([sense_, spec_])
out = widgets.interactive_output(leaf_plot, {'sense': sense_, 'spec': spec_})
display(ui, out)
如何导出它以便在浏览器中将其视为独立网页,例如 HTML,同时保留交互性,例如在 https://gabgoh.github.io/COVID/index.html ?
使用 plotly 的 fig.write_html() 选项我得到了一个独立的网页,但这样我就失去了滑块。
经过一些修改,plotly 最多允许单个滑块(ipywidgets 不包含在 plotly 图形对象中)。
此外,在情节上,所述滑块基本上控制了预先计算的轨迹的可见性(参见 https://plotly.com/python/sliders/),这限制了交互性(有时参数 space 很大)。
最好的方法是什么?
(我不一定要坚持plotly/ipywidgets)
用plotly,创建图形后,保存:
fig.write_html("path/to/file.html")
在函数中也试试这个参数:
animation_opts:字典或None(默认None)
要传递给函数的自定义动画参数的字典
Plotly.animate 在 Plotly.js 中。看
https://github.com/plotly/plotly.js/blob/master/src/plots/animation_attributes.js
可用选项。如果图形不包含则无效
帧,或 auto_play 为 False。
否则,请在此处查看一些建议:https://community.plotly.com/t/export-plotly-and-ipywidgets-as-an-html-file/18579
你需要稍微修改一下,但你可以用 dash and Heroku 实现你想要的。
首先您需要将 leaf_plot() 修改为 return 图形对象。
from numpy import linspace
def leaf_plot(sense, spec):
fig = go.Figure()
x = linspace(0,1,101)
x[0] += 1e-16
x[-1] -= 1e-16
positive = sense*x/(sense*x + (1-spec)*(1-x))
negative = 1-spec*(1-x)/((1-sense)*x + spec*(1-x))
fig.add_trace(
go.Scatter(x=x, y = positive, name="Positive",marker=dict( color='red'))
)
fig.add_trace(
go.Scatter(x=x, y = negative,
name="Negative",
mode = 'lines+markers',
marker=dict( color='green'))
)
fig.update_layout(
xaxis_title="Base rate",
yaxis_title="After-test probability",
)
return fig
然后写dash app:
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
# Build App
app = JupyterDash(__name__)
app.layout = html.Div([
html.H1("Interpreting Test Results"),
dcc.Graph(id='graph'),
html.Label([
"sensitivity",
dcc.Slider(
id='sensitivity-slider',
min=0,
max=1,
step=0.01,
value=0.5,
marks = {i: '{:5.2f}'.format(i) for i in linspace(1e-16,1-1e-16,11)}
),
]),
html.Label([
"specificity",
dcc.Slider(
id='specificity-slider',
min=0,
max=1,
step=0.01,
value=0.5,
marks = {i: '{:5.2f}'.format(i) for i in linspace(1e-16,1-1e-16,11)}
),
]),
])
# Define callback to update graph
@app.callback(
Output('graph', 'figure'),
Input("sensitivity-slider", "value"),
Input("specificity-slider", "value")
)
def update_figure(sense, spec):
return leaf_plot(sense, spec)
# Run app and display result inline in the notebook
app.run_server()
如果您在 jupyter notebook 中执行此操作,您将只能在本地访问您的应用程序。
如果要发布,可以试试Heroku
我在python中有这个互动情节:
import ipywidgets as widgets
import plotly.graph_objects as go
from numpy import linspace
def leaf_plot(sense, spec):
fig = go.Figure()
x = linspace(0,1,101)
x[0] += 1e-16
x[-1] -= 1e-16
positive = sense*x/(sense*x + (1-spec)*(1-x))
#probability a person is infected, given a positive test result,
#P(p|pr) = P(pr|p)*P(p)/P(pr)
# = P(pr|p)*P(p)/(P(pr|p)*P(p) + P(pr|n)*P(n))
# = sense*P(p)/( sense*P(p) +(1-spec)*P(n))
negative = 1-spec*(1-x)/((1-sense)*x + spec*(1-x))
fig.add_trace(
go.Scatter(x=x, y = positive, name="Positive",marker=dict( color='red'))
)
fig.add_trace(
go.Scatter(x=x, y = negative,
name="Negative",
mode = 'lines+markers',
marker=dict( color='green'))
)
fig.update_xaxes(title_text = "Base Rate")
fig.update_yaxes(title_text = "Post-test Probability")
fig.show()
sense_ = widgets.FloatSlider(
value=0.5,
min=0,
max=1.0,
step=0.01,
description='Sensitivity:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='.2f',
)
spec_ = widgets.FloatSlider(
value=0.5,
min=0,
max=1.0,
step=0.01,
description='Specificity:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='.2f',
)
ui = widgets.VBox([sense_, spec_])
out = widgets.interactive_output(leaf_plot, {'sense': sense_, 'spec': spec_})
display(ui, out)
如何导出它以便在浏览器中将其视为独立网页,例如 HTML,同时保留交互性,例如在 https://gabgoh.github.io/COVID/index.html ?
使用 plotly 的 fig.write_html() 选项我得到了一个独立的网页,但这样我就失去了滑块。
经过一些修改,plotly 最多允许单个滑块(ipywidgets 不包含在 plotly 图形对象中)。
此外,在情节上,所述滑块基本上控制了预先计算的轨迹的可见性(参见 https://plotly.com/python/sliders/),这限制了交互性(有时参数 space 很大)。
最好的方法是什么?
(我不一定要坚持plotly/ipywidgets)
用plotly,创建图形后,保存:
fig.write_html("path/to/file.html")
在函数中也试试这个参数:
animation_opts:字典或None(默认None) 要传递给函数的自定义动画参数的字典 Plotly.animate 在 Plotly.js 中。看 https://github.com/plotly/plotly.js/blob/master/src/plots/animation_attributes.js 可用选项。如果图形不包含则无效 帧,或 auto_play 为 False。
否则,请在此处查看一些建议:https://community.plotly.com/t/export-plotly-and-ipywidgets-as-an-html-file/18579
你需要稍微修改一下,但你可以用 dash and Heroku 实现你想要的。
首先您需要将 leaf_plot() 修改为 return 图形对象。
from numpy import linspace
def leaf_plot(sense, spec):
fig = go.Figure()
x = linspace(0,1,101)
x[0] += 1e-16
x[-1] -= 1e-16
positive = sense*x/(sense*x + (1-spec)*(1-x))
negative = 1-spec*(1-x)/((1-sense)*x + spec*(1-x))
fig.add_trace(
go.Scatter(x=x, y = positive, name="Positive",marker=dict( color='red'))
)
fig.add_trace(
go.Scatter(x=x, y = negative,
name="Negative",
mode = 'lines+markers',
marker=dict( color='green'))
)
fig.update_layout(
xaxis_title="Base rate",
yaxis_title="After-test probability",
)
return fig
然后写dash app:
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
# Build App
app = JupyterDash(__name__)
app.layout = html.Div([
html.H1("Interpreting Test Results"),
dcc.Graph(id='graph'),
html.Label([
"sensitivity",
dcc.Slider(
id='sensitivity-slider',
min=0,
max=1,
step=0.01,
value=0.5,
marks = {i: '{:5.2f}'.format(i) for i in linspace(1e-16,1-1e-16,11)}
),
]),
html.Label([
"specificity",
dcc.Slider(
id='specificity-slider',
min=0,
max=1,
step=0.01,
value=0.5,
marks = {i: '{:5.2f}'.format(i) for i in linspace(1e-16,1-1e-16,11)}
),
]),
])
# Define callback to update graph
@app.callback(
Output('graph', 'figure'),
Input("sensitivity-slider", "value"),
Input("specificity-slider", "value")
)
def update_figure(sense, spec):
return leaf_plot(sense, spec)
# Run app and display result inline in the notebook
app.run_server()
如果您在 jupyter notebook 中执行此操作,您将只能在本地访问您的应用程序。
如果要发布,可以试试Heroku