在Windows 10上通过Anaconda(导航器v.9.7.0)使用Jupyter Notebook(v.0.0.0),请考虑以下情况:我在顶部放置了一个ipywidgets
滑块,然后在其中插入了很多文本,然后是botton上响应滑块的图形。这是Firefox中这样的网页的图像,将其缩小以便可以完整显示:
很显然,这很难使用-在这种情况下,我更希望“分离”包含滑块的小部件,并将其向下拖动到图形所在的位置,然后操作该滑块;在这种情况下,我也不必使用缩小的网页渲染。然后,在完成操作后,我想单击一个按钮,然后将小部件重新连接到原来的位置。
但是,我不确定如何在ipywidgets
的Jupyter笔记本中实现此功能?我发现与此最接近的是[Question] Maintain position of floating widget when browser tab is closed · Issue #2520 · jupyter-widgets/ipywidgets,这似乎意味着需要对JavaScript进行干预。
这是重新创建屏幕截图的代码(在包含滑块的小部件中已经有一个“分离”按钮,除了更改文本以外,它什么都不做):
单元1-Python 3:
import plotly.graph_objs as go
import numpy as np
from ipywidgets import widgets, Layout
from IPython.display import display
from IPython.display import Markdown as md
inSlider = widgets.FloatSlider(
value=1.0,
min=0.0,
max=10.0,
step=0.01,
description='In:',
continuous_update=True
)
output2 = widgets.Output()
def on_detButton_click(b):
if b.description == "Detach": b.description = "Attach"
else: b.description = "Detach"
detButton = widgets.Button(description="Detach")
detButton.on_click(on_detButton_click)
myctlwidget = widgets.VBox([widgets.HBox([inSlider, detButton]), output2])
display(myctlwidget)
单元格2是Markdown-粘贴在这篇文章的结尾;
单元3-Python 3:
fig = go.FigureWidget( layout=go.Layout() )
fig.add_trace(go.Scatter(x=[0,10], y=[0,10],
mode='lines',
name='Test plot'))
# set range to prevent autoranging when slider sets a new value
fig.update_yaxes(range=[0, 11])
def update_graph(change):
with fig.batch_update():
curval = inSlider.value
fig.data[0].y=[0, curval]
inSlider.observe(update_graph, names="value")
widgets.VBox([fig])
第2单元-降价(注意每行第一行的末尾有两个空格,以引入换行符)
Test paragraph 0
Some text 0, 0.... some text 0
Test paragraph 1
Some text 1, 1.... some text 1
Test paragraph 2
Some text 2, 2.... some text 2
Test paragraph 3
Some text 3, 3.... some text 3
Test paragraph 4
Some text 4, 4.... some text 4
Test paragraph 5
Some text 5, 5.... some text 5
Test paragraph 6
Some text 6, 6.... some text 6
Test paragraph 7
Some text 7, 7.... some text 7
Test paragraph 8
Some text 8, 8.... some text 8
Test paragraph 9
Some text 9, 9.... some text 9
Test paragraph 10
Some text 10, 10.... some text 10
Test paragraph 11
Some text 11, 11.... some text 11
Test paragraph 12
Some text 12, 12.... some text 12
Test paragraph 13
Some text 13, 13.... some text 13
Test paragraph 14
Some text 14, 14.... some text 14
Test paragraph 15
Some text 15, 15.... some text 15
Test paragraph 16
Some text 16, 16.... some text 16
Test paragraph 17
Some text 17, 17.... some text 17
Test paragraph 18
Some text 18, 18.... some text 18
Test paragraph 19
Some text 19, 19.... some text 19
Test paragraph 20
Some text 20, 20.... some text 20
Test paragraph 21
Some text 21, 21.... some text 21
Test paragraph 22
Some text 22, 22.... some text 22
Test paragraph 23
Some text 23, 23.... some text 23
Test paragraph 24
Some text 24, 24.... some text 24
Test paragraph 25
Some text 25, 25.... some text 25
Test paragraph 26
Some text 26, 26.... some text 26
Test paragraph 27
Some text 27, 27.... some text 27
Test paragraph 28
Some text 28, 28.... some text 28
Test paragraph 29
Some text 29, 29.... some text 29
Test paragraph 30
Some text 30, 30.... some text 30
答案 0 :(得分:1)
好的,我想我可以正常工作了-值得庆幸的是,此版本的Jupyter笔记本自动加载jquery-ui
,因此我可以使用.draggable()
...
请注意:
如果有人想出(第二个)问题的解决方案,我很想听听。
同时,解决方法是将一个简单的Markdown单元放置在包含绘图的单元输出下方,该单元随后将能够正确地“托管”拖动的滑块元素。在这种情况下,修复程序如下所示(小“(h)”是句柄):
这是我的解决方法:
单元1-Python 3:
import plotly.graph_objs as go
import numpy as np
from ipywidgets import widgets, Layout
from IPython.display import display, Javascript
from IPython.display import Markdown as md
inSlider = widgets.FloatSlider(
value=1.0,
min=0.0,
max=10.0,
step=0.01,
description='In:',
continuous_update=True
)
output2 = widgets.Output()
def on_detButton_click(b):
if b.description == "Detach":
b.description = "Attach"
# must wrap in display() - Javascript() call on its own does not effectuate!
# https://stackoverflow.com/questions/15193640/jquery-ui-draggable-reset-to-original-position
# NOTE: in spite of zIndex manipulation: do NOT place dragged widget over textarea (it will lose focus),
# also, it will be under a plot.ly diagram regardless!
display(Javascript("""
var $dragwidget = $("div.myctlwidget").parent();
$dragwidget.data({
'originalLeft': $dragwidget.css('left'),
'originalTop': $dragwidget.css('top'),
'originalZindex': $dragwidget.css('z-index')
});
$dragwidget.css({ 'z-index': 5000});
$dragwidget.draggable({ disabled: false, handle: "div.myctlhandle" });
"""))
else:
b.description = "Detach"
display(Javascript("""
var $dragwidget = $("div.myctlwidget").parent();
$dragwidget.draggable({ disabled: true });
$dragwidget.css({
'left': $dragwidget.data('originalLeft'),
'top': $dragwidget.data('originalTop'),
'z-index': $dragwidget.data('originalZindex'),
});
"""))
detButton = widgets.Button(description="Detach")
detButton.on_click(on_detButton_click)
# NB: Button still is visually clickable, even when disabled :(
handleButton = widgets.Label("(h)", _dom_classes = ['myctlhandle'])
myctlwidget = widgets.VBox([widgets.HBox([inSlider, detButton, handleButton])], _dom_classes = ['myctlwidget'])
display(myctlwidget)
#myctlwidget._dom_classes = ['myctlwidget'] # nowork; only added as argument to VBox _dom_classes works!
#print(myctlwidget._dom_classes)
单元3-Python 3:
fig = go.FigureWidget( layout=go.Layout() )
fig.add_trace(go.Scatter(x=[0,10], y=[0,10],
mode='lines',
name='Test plot'))
# set range to prevent autoranging
fig.update_yaxes(range=[0, 11])
def update_graph(change):
with fig.batch_update():
curval = inSlider.value
fig.data[0].y=[0, curval]
inSlider.observe(update_graph, names="value")
#spacer = widgets.VBox([widgets.Text(": :"), widgets.Label(": :")]) # nope
display(md("Markdown here does NOT work as spacer!\n\n... does NOT work as spacer!"))
display(widgets.VBox([fig]))