微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

努力使用ipywidgets为图调用多个交互功能

如何解决努力使用ipywidgets为图调用多个交互功能

我正在寻找一个主图像,在该主图像上绘制螺旋形,椭圆形等,其变量会更改所施加的图形的形状。主图像还需要具有对比度变量。

我的代码当前看起来像这样;




###############################################BASIC figURE PLOT####################################
plt.figure(figsize=(24,24))
@interact
def spiral(Spiral=False,n=2000,x1=50,y1=50,z1=50,k1=300):
    if Spiral == False:
        x = 0;
        y = 0;
        plt.scatter(x,y,s = 3,c = 'black');
    else:
        angle = np.linspace(x1,y1*1*np.pi,n)
        radius = np.linspace(z1,k1,n)
        x = radius * np.cos(angle) + 150
        y = radius * np.sin(angle) + 150
        plt.scatter(x,c = 'black');
@interact        
def contrast(vuc=(0.2,1,0.01),vlc=(0.1,0.01)):  
    vu = np.quantile(qphi,vuc);
    vl = np.quantile(qphi,vlc);
    print("upper =",vu," lower=",vl);


plt.imshow(qphi,origin='lower',vmin=vl,vmax=vu);
plt.show() 

这将产生两个情节; visible here 一个可以产生螺旋的图可以自由编辑,另一个可以作为主要图像的对比度可变的图。

任何有关如何结合这两种情节的建议将不胜感激;谢谢!

解决方法

有几种方法可以使用ipywidgets控制matplotlib图。在下面创建的输出中,我认为您正在寻找使用每个选项的输出。这些方法按照发现的自然顺序列出,但是,我建议按以下顺序尝试:4,2,1,3

方法1-内联后端

如果您使用%matplotlib inline,则matplotlib图形将不会交互,因此您每次都需要重新创建整个图

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact

# load fake image data
from matplotlib import cbook
img = plt.imread(cbook.get_sample_data("grace_hopper.jpg")).mean(axis=-1)


@interact
def graph(
    Spiral=True,n=2000,x1=50,y1=50,z1=50,k1=300,vlc=(0.1,0.01),vuc=(0.1,):
    fig,(ax1,ax2) = plt.subplots(1,figsize=(12,5))
    if Spiral == False:
        x = 0
        y = 0
    else:
        angle = np.linspace(x1,y1 * 1 * np.pi,n)
        radius = np.linspace(z1,k1,n)
        x = radius * np.cos(angle) + 150
        y = radius * np.sin(angle) + 150
    ax1.scatter(x,y,s=3,color="k")
    vu = np.quantile(img,vuc)
    vl = np.quantile(img,vlc)
    ax2.imshow(img,vmin=vl,vmax=vu)

方法2-交互式后端+ cla

您可以使用交互式maptlotlib后端之一来避免每次更改时都必须完全重新生成图形。为此,第一种方法是使用cla方法在每次滑块改变时简单地清除轴。

这将与%matplotlib notebook%matplotlib ipympl一起使用。前者将仅在jupyter笔记本中工作,而后者将在jupyter笔记本和juptyerlab中工作。 (此处为ipympl的安装信息:https://github.com/matplotlib/ipympl#installation

%matplotlib ipympl

import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact,interactive,interactive_output

# load fake image data
from matplotlib import cbook
img = plt.imread(cbook.get_sample_data("grace_hopper.jpg")).mean(axis=-1)


fig,5))


@interact
def graph(
    Spiral=True,):
    ax1.cla()
    ax2.cla()
    if Spiral == False:
        x = 0
        y = 0
    else:
        angle = np.linspace(x1,vmax=vu)

方法3-交互式后端+ set_data

在绘制较大的数据集或要从一个交互作用到另一个交互作用要保留的某些部分绘图时,完全清除轴可能效率不高。因此,您可以改用set_dataset_offsets方法来更新已经绘制的内容。

%matplotlib ipympl

import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact,5))
scat = ax1.scatter([0]*2000,[0]*2000,color='k')
im = ax2.imshow(img)

out = widgets.Output()
display(out)

@interact
def graph(
    Spiral=True,):
    if Spiral == False:
        x = 0
        y = 0
    else:
        angle = np.linspace(x1,n)
        x = radius * np.cos(angle) + 150
        y = radius * np.sin(angle) + 150
    scat.set_offsets(np.c_[x,y])
    # correctly scale the x and y limits
    ax1.dataLim = scat.get_datalim(ax1.transData)
    ax1.autoscale_view()

    vu = np.quantile(img,vlc)
    im.norm.vmin = vl
    im.norm.vmax = vu

方法4-mpl_interactions

使用set_offsets和等效的set_data将是性能最高的解决方案,但是要弄清楚如何使其工作甚至要记住起来也很棘手。为了简化起见,我创建了一个库(mpl-interactions),该库可自动执行方法3的样板。

除了简单易行且性能卓越之外,它还具有以下优点:您不必负责更新绘图,而只负责返回正确的值。这样一来,它便具有辅助优势,现在像spiral这样的函数可以在代码的其他部分使用,因为它们只是返回值而不是处理绘图。

另一个优势是mpl-interactions还可以创建matplotlib小部件,因此这是唯一一种在笔记本之外也可以使用的方法。

%matplotlib ipympl
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
import mpl_interactions.ipyplot as iplt

img = plt.imread(cbook.get_sample_data("grace_hopper.jpg")).mean(axis=-1)

# define the functions to be plotted
def spiral(Spiral=False,k1=300):
    if Spiral == False:
        x = 0
        y = 0
        return x,y
    else:
        angle = np.linspace(x1,n)
        x = radius * np.cos(angle) + 150
        y = radius * np.sin(angle) + 150
        return x,y


def vmin(vuc,vlc):
    return np.quantile(img,vlc)

def vmax(vlc,vuc):
    return np.quantile(img,vuc)


fig,5))
controls = iplt.scatter(
    spiral,Spiral={(True,False)},n=np.arange(1800,2200),x1=(25,75),y1=(25,z1=(25,k1=(200,400),parametric=True,c="black",ax=ax1,)
controls = iplt.imshow(
    img,vmin=vmin,vmax=vmax,1000),controls=controls[None],ax=ax2,)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。