Jupyter中matplotlib绘图的持续更新
Continious update of matplotlib plot in Jupyter
我正在研究 Jupyter Notebook
,我正在使用以下 ipywidget
来设置阈值:
Thr = widgets.IntSlider(value=-17, min=-30, max=-13, step=1, description='Threshold: ', disabled=False, continuous_update=True, orientation='horizontal', readout=True, readout_format='d')
Thr
接下来,我使用该值屏蔽 numpy array
:
import numpy.ma as ma
test= ma.masked_less_equal(S_images[0], Thr.value)
最后我绘制了结果:
plt.figure(figsize = (15,15))
plt.imshow(test[0], cmap='gray')
ipywidget
与其他代码的 Jupyter cell
不同,因此当我更改 Thr
的值时,我必须再次手动 运行 所在的单元格进行掩蔽和绘图。
我的问题是:我一直看到那些交互式绘图,您可以在其中更改参数(在我的例子中是 ipywidget Thr
)并自动更新绘图。
我看到 widgets.IntSlider
有一个 continuous_update
参数,它似乎接近我想要的但仍然无法获得我想要的行为。
知道这是否可行吗?
_ 编辑 _
从ac24的评论开始,我正在改编他提出的例子:
from IPython.display import display, clear_output
import ipywidgets as ipy
import matplotlib.pyplot as plt
import numpy as np
# setup figure
n = 10
out = ipy.Output()
# show random mesh
def update(idx):
with out:
clear_output()
fig, ax = plt.subplots(figsize = (5,5))
h = ax.imshow(S_images[0]) # here I put my image
h.set_data(np.ma.masked_less_equal(S_images[0], slider.value)) # here I set the task to masked accordint to the `slider.value`
fig.canvas.flush_events()
fig.canvas.draw()
plt.show()
slider = ipy.IntSlider(min = 0, max = 10, orientation = 'vertical')
widget = ipy.interactive(update, idx = slider)
layout = ipy.Layout(
# display = 'flex',
# flex_flow = 'row',
# justify_content = 'space-between',
# align_items = 'center',
)
widgets = ipy.HBox(children=(slider, out), layout = layout)
display(widgets)
这个例子非常好用,正是我想要的。但是,我对布局有一个小问题。最初我正在处理 3 张图片,所以我想让它们显示如下,每张图片旁边都有它的滑块来完成任务:(下面的图片不是真实的,只是为了代表我想要的)
编辑 2
在这种情况下,问题是,一旦我 select 滑块中的一个值,我就会将那个光栅写入 geotiff。为此,我使用以下代码:
with rasterio.open('/Path/20190331_VV_Crop') as src:
ras_meta = src.profile
with rasterio.open('/path/Threshold.tif', 'w', **ras_meta) as dst:
dst.write(X)
但是,我不确定如何在 dst.write(X)
中引用 numpy 数组
我已将我给出的示例改编成 class,因为您想要 link 特定的输出和滑块实例,但要创建它们的多个组。设置输出小部件的布局可避免在您滑动滑块时小部件一直调整大小。
from IPython.display import display, clear_output
import ipywidgets as ipy
import matplotlib.pyplot as plt
import numpy as np
# setup figure
n = 10
class SliderAndImage():
# show random mesh
def update(self, idx):
with self.out:
clear_output()
fig, ax = plt.subplots(figsize = (5,5))
h = ax.imshow(np.random.rand(n, n))
h.set_data(np.random.rand(n, n))
fig.canvas.flush_events()
fig.canvas.draw()
plt.show()
def make_slider_and_image(self):
self.out = ipy.Output(layout=ipy.Layout(width='200px', height='200px'))
slider = ipy.IntSlider(min = 0, max = 10, orientation = 'vertical')
widget = ipy.interactive(self.update, idx = slider)
layout = ipy.Layout(
# display = 'flex',
# flex_flow = 'row',
# justify_content = 'space-between',
# align_items = 'center',
)
widgets = ipy.HBox(children=(slider, self.out), layout = layout)
return widgets
children = []
for _ in range(3):
widgets = SliderAndImage()
children.append(widgets.make_slider_and_image())
display(ipy.HBox(children))
我正在研究 Jupyter Notebook
,我正在使用以下 ipywidget
来设置阈值:
Thr = widgets.IntSlider(value=-17, min=-30, max=-13, step=1, description='Threshold: ', disabled=False, continuous_update=True, orientation='horizontal', readout=True, readout_format='d')
Thr
接下来,我使用该值屏蔽 numpy array
:
import numpy.ma as ma
test= ma.masked_less_equal(S_images[0], Thr.value)
最后我绘制了结果:
plt.figure(figsize = (15,15))
plt.imshow(test[0], cmap='gray')
ipywidget
与其他代码的 Jupyter cell
不同,因此当我更改 Thr
的值时,我必须再次手动 运行 所在的单元格进行掩蔽和绘图。
我的问题是:我一直看到那些交互式绘图,您可以在其中更改参数(在我的例子中是 ipywidget Thr
)并自动更新绘图。
我看到 widgets.IntSlider
有一个 continuous_update
参数,它似乎接近我想要的但仍然无法获得我想要的行为。
知道这是否可行吗?
_ 编辑 _
从ac24的评论开始,我正在改编他提出的例子:
from IPython.display import display, clear_output
import ipywidgets as ipy
import matplotlib.pyplot as plt
import numpy as np
# setup figure
n = 10
out = ipy.Output()
# show random mesh
def update(idx):
with out:
clear_output()
fig, ax = plt.subplots(figsize = (5,5))
h = ax.imshow(S_images[0]) # here I put my image
h.set_data(np.ma.masked_less_equal(S_images[0], slider.value)) # here I set the task to masked accordint to the `slider.value`
fig.canvas.flush_events()
fig.canvas.draw()
plt.show()
slider = ipy.IntSlider(min = 0, max = 10, orientation = 'vertical')
widget = ipy.interactive(update, idx = slider)
layout = ipy.Layout(
# display = 'flex',
# flex_flow = 'row',
# justify_content = 'space-between',
# align_items = 'center',
)
widgets = ipy.HBox(children=(slider, out), layout = layout)
display(widgets)
这个例子非常好用,正是我想要的。但是,我对布局有一个小问题。最初我正在处理 3 张图片,所以我想让它们显示如下,每张图片旁边都有它的滑块来完成任务:(下面的图片不是真实的,只是为了代表我想要的)
编辑 2
在这种情况下,问题是,一旦我 select 滑块中的一个值,我就会将那个光栅写入 geotiff。为此,我使用以下代码:
with rasterio.open('/Path/20190331_VV_Crop') as src:
ras_meta = src.profile
with rasterio.open('/path/Threshold.tif', 'w', **ras_meta) as dst:
dst.write(X)
但是,我不确定如何在 dst.write(X)
我已将我给出的示例改编成 class,因为您想要 link 特定的输出和滑块实例,但要创建它们的多个组。设置输出小部件的布局可避免在您滑动滑块时小部件一直调整大小。
from IPython.display import display, clear_output
import ipywidgets as ipy
import matplotlib.pyplot as plt
import numpy as np
# setup figure
n = 10
class SliderAndImage():
# show random mesh
def update(self, idx):
with self.out:
clear_output()
fig, ax = plt.subplots(figsize = (5,5))
h = ax.imshow(np.random.rand(n, n))
h.set_data(np.random.rand(n, n))
fig.canvas.flush_events()
fig.canvas.draw()
plt.show()
def make_slider_and_image(self):
self.out = ipy.Output(layout=ipy.Layout(width='200px', height='200px'))
slider = ipy.IntSlider(min = 0, max = 10, orientation = 'vertical')
widget = ipy.interactive(self.update, idx = slider)
layout = ipy.Layout(
# display = 'flex',
# flex_flow = 'row',
# justify_content = 'space-between',
# align_items = 'center',
)
widgets = ipy.HBox(children=(slider, self.out), layout = layout)
return widgets
children = []
for _ in range(3):
widgets = SliderAndImage()
children.append(widgets.make_slider_and_image())
display(ipy.HBox(children))