关于python:使用ipywidgets和plotly v4的Jupyter?

Jupyter with ipywidgets and plotly v4?

在Windows 10上使用Anaconda的Jupyter安装;还安装了conda install -c plotly plotly,并且显然安装了Plotly v4。

我只想从一个简单的示例开始-并使用ipywidget滑块而不是Plotly滑块。因此,我发现:

https://moderndata.plot.ly/widgets-in-ipython-notebook-and-plotly/

EXAMPLE 3: interact

A simple example of using the interact decorator from ipywidgets to create a simple set of widgets to control the parameters of a plot.

Link to IPython notebook

对-所以我转到了该链接,并将其中的代码重新组织为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import plotly.graph_objs as go
import numpy as np
from ipywidgets import interact

fig = go.FigureWidget()
scatt = fig.add_scatter()

xs=np.linspace(0, 6, 100)
fig.show()

@interact(a=(1.0, 4.0, 0.01), b=(0, 10.0, 0.01), color=['red', 'green', 'blue'])
def update(a=3.6, b=4.3, color='blue'):
    with fig.batch_update():
        scatt.x=xs
        scatt.y=np.sin(a*xs-b)
        scatt.line.color=color

...,当我运行此单元格时,它会绘制一个空图:

jupyter_plotly_fail.png

...,并失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
C:\\ProgramData\\Anaconda3\\lib\\site-packages\\ipywidgets\\widgets\\interaction.py in update(self, *args)
    254                     value = widget.get_interact_value()
    255                     self.kwargs[widget._kwarg] = value
--> 256                 self.result = self.f(**self.kwargs)
    257                 show_inline_matplotlib_plots()
    258                 if self.auto_display and self.result is not None:

<ipython-input-21-7dcd6b5f2be1> in update(a, b, color)
     12 def update(a=3.6, b=4.3, color='blue'):
     13     with fig.batch_update():
---> 14         scatt.x=xs
     15         scatt.y=np.sin(a*xs-b)
     16         scatt.line.color=color

C:\\ProgramData\\Anaconda3\\lib\\site-packages\\plotly\\basedatatypes.py in __setattr__(self, prop, value)
    349         else:
    350             # Raise error on unknown public properties
--> 351             raise AttributeError(prop)
    352
    353     def __getitem__(self, prop):

AttributeError: x

显然,这是因为Plotly v4中进行了足够的更改,以保证有版本4迁移指南|阴谋地通过浏览,我试图像这样修改代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import plotly.graph_objs as go
import numpy as np
from ipywidgets import interact

fig = go.FigureWidget()
scattf = fig.add_scatter()
scatt = scattf.data[-1]

xs=np.linspace(0, 6, 100)
scattf.show()

@interact(a=(1.0, 4.0, 0.01), b=(0, 10.0, 0.01), color=['red', 'green', 'blue'])
def update(a=3.6, b=4.3, color='blue'):
    with fig.batch_update():
        scatt.x=xs
        scatt.y=np.sin(a*xs-b)
        scatt.line.color=color

...现在我不再收到错误-但是该图仍然为空,并且在拖动滑块时不会更新。

有人可以告诉我,如何使该示例正常工作,以便在拖动滑块时绘制图并进行更新/重绘?

编辑:有点混乱了,现在我有了这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import plotly.graph_objs as go
import numpy as np
from ipywidgets import interact

fig = go.FigureWidget()
scattf = fig.add_scatter()
scatt = scattf.data[-1]

xs=np.linspace(0, 6, 100)
#scattf.show() # adds extra plot, if there is scattf.show() in update()!

@interact(a=(1.0, 4.0, 0.01), b=(0, 10.0, 0.01), color=['red', 'green', 'blue'])
def update(a=3.6, b=4.3, color='blue'):
    with fig.batch_update():
        scatt.x=xs
        scatt.y=np.sin(a*xs-b)
        scatt.line.color=color
        scattf.show()

update() # update once; so we don't get empty plot at start? not really - still getting empty plot at start, and another one after which is updated

这里有两个问题:

  • 运行单元格后,首先绘制一个空的图,然后绘制另一个图-如何获取仅绘制默认值的图? (没有最后一个update(),只有一个图,但是开始时为空-必须拖动滑块使其开始绘制)
  • 现在,在拖动滑块时,绘图会发生变化-但它会闪烁很多。有什么办法可以减少闪烁?


在Jupyter笔记本电脑或JupyterLab环境中,您可以这样操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
import plotly.graph_objects as go
from ipywidgets import interact

xs=np.linspace(0, 6, 100)

fig = go.FigureWidget()
fig.add_scatter()

@interact(a=(1.0, 4.0, 0.01), b=(0, 10.0, 0.01), color=['red', 'green', 'blue'])
def update(a=3.6, b=4.3, color='blue'):
    with fig.batch_update():
        fig.data[0].x=xs
        fig.data[0].y=np.sin(a*xs-b)
        fig.data[0].line.color=color
fig

enter image description here


是的,因此找到了使用FigureWidget ipywidgets进行交互式数据分析-并相应地重写了示例;这具有更平滑的响应,并且不会出现两次抽签-但是,我仍然不确定这是否是这样做的方法;所以如果有人知道更好,请发表...

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
import plotly.graph_objs as go
import numpy as np
#from ipywidgets import interact, interactive
from ipywidgets import widgets
from IPython.display import display

aSlider = widgets.FloatSlider(
    value=2.0,
    min=1.0,
    max=4.0,
    step=0.01,
    description='a:',
    continuous_update=False
)

bSlider = widgets.FloatSlider(
    value=1.0,
    min=0.0,
    max=10.0,
    step=0.01,
    description='b:',
    continuous_update=True
)

colorDropdown = widgets.Dropdown(
    description='Color:',
    value='blue',
    options=['red', 'blue', 'green']
)

fig = go.FigureWidget()
#fig.show()
scattf = fig.add_scatter()
scatt = scattf.data[-1]

xs=np.linspace(0, 6, 100)

def response(change):
    with fig.batch_update():
        fig.data[0].x=xs
        fig.data[0].y=np.sin(aSlider.value*xs-bSlider.value)
        fig.data[0].line.color=colorDropdown.value
        fig.layout.xaxis.title = 'whatever'

aSlider.observe(response, names="value")
bSlider.observe(response, names="value")
colorDropdown.observe(response, names="value")

response("doesn't matter what I send here, just triggering") # MUST be before widgets.VBox - if response(x) is last, NOTHING is drawn!

widgets.VBox([aSlider,
              bSlider,
              colorDropdown,
              fig])