【问题标题】:Multiple imshow on the same plot, with opacity slider同一图上的多个 imshow,带有不透明度滑块
【发布时间】:2022-11-04 03:01:48
【问题描述】:

使用 Plotly,我想在同一页面上显示两个 imshow,在同一位置,不透明。

这几乎有效:

import plotly.express as px, numpy as np
from skimage import io
img = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg')
fig = px.imshow(img)
x = np.random.random((100, 200))
fig2 = px.imshow(x)
fig.show()
fig2.show()

但它会在两个不同的选项卡中显示两个 imshow 图像。

如何在同一个图上显示两个“imshow”,两个图层都有一个不透明度滑块?

作为参考,这里是 matplotlib 等价物:

import numpy as np, matplotlib.pyplot as plt, matplotlib.widgets as mpwidgets, scipy.misc
x = scipy.misc.face(gray=False)     # shape (768, 1024, 3)
y = np.random.random((100, 133))    # shape (100, 133)
fig, (ax0, ax1) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [5, 1]})
OPACITY = 0.5
img0 = ax0.imshow(x, cmap="jet")
img1 = ax0.imshow(y, cmap="jet", alpha=OPACITY, extent=img0.get_extent())
slider0 = mpwidgets.Slider(ax=ax1, label='opacity', valmin=0, valmax=1, valinit=OPACITY)
slider0.on_changed(lambda value: img1.set_alpha(value))
plt.show()

【问题讨论】:

  • 我不确定我是否理解这些要求。比如说,滑块值是v。您希望两张图像都具有不透明度v,或者一个具有不透明度v,另一个具有1-v?此外,在您的 sn-p 中,y 将出现在 x 之上 - 对于 v 的所有值,它是否应该保持这种状态?
  • @YuliaV v 对于一个和 1-v 对于另一个将是完美的(在我的情况下,我的做法略有不同 - 一个总是以不透明度显示 1 - 但在这里没关系)。
  • @YuliaV 在我的示例中 y 位于顶部,但是当不透明度接近 0 时,它就会消失。任何允许用户从一个 imshow 顺利(不透明)转到另一个 imshow 的组合都是完美的。
  • 您使用的是哪个 IDE?

标签: python numpy plotly plotly-python


【解决方案1】:

主要问题是预先计算所有跟踪是在 Plotly 中创建 layer.Slider 的必要步骤,如文档中的 here 所示。因此,我们希望计算唯一需要的跟踪on the fly,而不是预先计算所有跟踪。此外,我完全同意你的观点,在用户机器上预先构建所有跟踪是无效的解决方案,因为这将花费很长时间并消耗大量内存,尤其是在图像尺寸很大的情况下。

从我的角度来看,我认为最好的选择是同时使用Plotlyipywidgets,与第一个选项相比,这样做可以节省更多的时间和内存。

完整代码

import plotly.express as px
import plotly.graph_objects as go
from skimage import io 
import numpy as np
from PIL import Image
from ipywidgets import FloatSlider, VBox

img = io.imread("https://images.unsplash.com/photo-1543349689-9a4d426bee8e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=801&q=80")
noise = np.random.random(img.shape[:2]) 


fig = go.FigureWidget(px.imshow(img))

fig.add_trace(go.Heatmap(z=noise, opacity=0.0, 
                         showscale=False, colorscale ="Greys",
                         name = "noise"))

def update(value):
    fig.update_traces(opacity=value["new"],selector=({'name':'noise'}))

Opacity_slider = FloatSlider(value=0.0,min=0.0,max=1.0,
                             step=0.1, description='Opacity:')

Opacity_slider.observe(update, names="value")

vb = VBox((fig, Opacity_slider))
vb.layout.align_items = 'center'
display(vb)

输出

【讨论】:

  • 谢谢您的回答!对于我的应用程序,我不使用 Jupyter 笔记本,而只使用 Plotly。或者也许我们可以在 Plotly 仪表板中间使用 Jupyter Widget,而不使用 Jupyter 笔记本?您是否有示例代码可以使用layout.slider 实时更新不透明度?
  • @Basj 尝试使用animation_frame,如plotly.com/python/imshow
  • @Basj,但您应该创建具有不同不透明度的嘈杂图像作为框架并将其提供给 px.imshow 以获取滑块。
  • 我想我们可以实时计算它(=当滑块移动时),因为如果我们应该发送到网络客户端全部噪声图像的变化,这是很多不必要的数据(正常数据量的 255 倍)。你有没有 JupyterLab 的带滑块的代码示例吗?
  • 您是否有一个带有滑块的示例代码,而无需预先计算所有内容?通常使用滑块,我们可以动态计算新数据。
【解决方案2】:

我环顾四周,似乎滑块需要预先计算每个跟踪。但是,我有一个不占用大量内存的解决方案。

import plotly.express as px, numpy as np
from skimage import io 

img = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg')
x = np.random.random((len(img), len(img[0])))

fig = go.Figure()

fig.add_trace(go.Image(z=img))

for step in np.arange(0, 1.1, 0.1):
    fig.add_trace(go.Heatmap(z=x,
                 showscale=False,
                 opacity=step))

for n in range(1, len(fig.data)):
    fig.data[n].visible = False

fig.data[6].visible = True

steps = []
for i in range(1, len(fig.data)):
    step = dict(
        method = 'restyle',
        args = ['visible', [False] * len(fig.data)],
        )
    step['args'][1][0] = True
    step['args'][1][i] = True
    steps.append(step)
sliders = [dict(
    active=5,
    steps=steps
    )]

fig.layout.sliders = sliders
fig.show()

【讨论】:

    猜你喜欢
    • 2022-10-19
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 2015-05-03
    • 2018-03-24
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多