gpt4 book ai didi

python - 在 Jupyter - Python 中有 2 个 Ipywidgets 作用于一个 matplotlib 图

转载 作者:太空宇宙 更新时间:2023-11-04 08:31:55 25 4
gpt4 key购买 nike

以下代码模拟机器学习、线性回归过程。

它旨在允许用户在 Jupyter notebook 中手动和可视化地进行回归,以更好地感受线性回归过程。

函数的第一部分 (x,y) 生成一个图来执行回归。

下一部分 (a,b) 生成用于模拟回归的直线。

我希望能够在不重新生成散点图的情况下更改斜率 slider 。

任何指导都将非常有帮助和受欢迎。 :-)

import numpy as np
import ipywidgets as widgets
from ipywidgets import interactive
import matplotlib.pyplot as plt

def scatterplt(rand=3, num_points=20, slope=1):

x = np.linspace(3, 9, num_points)
y = np.linspace(3, 9, num_points)

#add randomness to scatter
pcent_rand = rand
pcent_decimal = pcent_rand/100
x = [n*np.random.uniform(low=1-pcent_decimal, high=1+ pcent_decimal) for n in x]
y = [n*np.random.uniform(low=1-pcent_decimal, high=1+ pcent_decimal) for n in y]

#plot regression line
a = np.linspace(0, 9, num_points)
b = [(slope * n) for n in a]

#format & plot the figure
plt.figure(figsize=(9, 9), dpi=80)
plt.ylim(ymax=max(x)+1)
plt.xlim(xmax=max(x)+1)

plt.scatter(x, y)

plt.plot(a, b)

plt.show()


#WIDGETS

interactive_plot = interactive(scatterplt,
rand = widgets.FloatSlider(
value=3,
min=0,
max=50,
step=3,
description='Randomness:', num_points=(10, 50, 5)
),
num_points = widgets.IntSlider(
value=20,
min=10,
max=50,
step=5,
description='Number of points:'
),
slope=widgets.FloatSlider(
value=1,
min=-1,
max=5,
step=0.1,
description='Slope'
)

)

interactive_plot

最佳答案

interactive 功能并不能真正让您访问这种级别的粒度。它始终运行整个 scatterplt 回调。基本上,interactive 的目的是让一类问题变得非常简单——一旦你摆脱了那类问题,它就不再适用了。

然后您必须回退到其余的小部件机制。最初这可能有点难以理解,因此,为了尽量减少跳转,我将首先解释 interactive 在幕后做了什么。

当您调用 interactive(func, widget) 时,它会创建 widget 并在该 widget 更改时绑定(bind)回调。回调在 Output 小部件 ( docs ) 中运行 funcOutput 小部件捕获 func 的整个输出。 interactive 然后将 widget 和输出小部件打包到 VBox(用于堆叠小部件的容器)中。

回到你现在想做的事。您的申请符合以下条件:

  1. 我们需要维护某种形式的内部状态:应用程序需要记住随机变量的 x 和 y 位置
  2. 我们需要根据触发的 slider 运行不同的行为。

要满足 (1),我们可能应该创建一个类来维护状态。为了满足 (2),我们需要根据调用的 slider 运行不同的回调。

这样的事情似乎可以满足您的需要:

import numpy as np
import ipywidgets as widgets
import matplotlib.pyplot as plt

class LinRegressDisplay:

def __init__(self, rand=3.0, num_points=20, slope=1.0):
self.rand = rand
self.num_points = num_points
self.slope = slope
self.output_widget = widgets.Output() # will contain the plot
self.container = widgets.VBox() # Contains the whole app
self.redraw_whole_plot()
self.draw_app()

def draw_app(self):
"""
Draw the sliders and the output widget

This just runs once at app startup.
"""
self.num_points_slider = widgets.IntSlider(
value=self.num_points,
min=10,
max=50,
step=5,
description='Number of points:'
)
self.num_points_slider.observe(self._on_num_points_change, ['value'])
self.slope_slider = widgets.FloatSlider(
value=self.slope,
min=-1,
max=5,
step=0.1,
description='Slope:'
)
self.slope_slider.observe(self._on_slope_change, ['value'])
self.rand_slider = widgets.FloatSlider(
value=self.rand,
min=0,
max=50,
step=3,
description='Randomness:', num_points=(10, 50, 5)
)
self.rand_slider.observe(self._on_rand_change, ['value'])
self.container.children = [
self.num_points_slider,
self.slope_slider,
self.rand_slider ,
self.output_widget
]

def _on_num_points_change(self, _):
"""
Called whenever the number of points slider changes.

Updates the internal state, recomputes the random x and y and redraws the plot.
"""
self.num_points = self.num_points_slider.value
self.redraw_whole_plot()

def _on_slope_change(self, _):
"""
Called whenever the slope slider changes.

Updates the internal state, recomputes the slope and redraws the plot.
"""
self.slope = self.slope_slider.value
self.redraw_slope()

def _on_rand_change(self, _):
self.rand = self.rand_slider.value
self.redraw_whole_plot()

def redraw_whole_plot(self):
"""
Recompute x and y random variates and redraw whole plot

Called whenever the number of points or the randomness changes.
"""
pcent_rand = self.rand
pcent_decimal = pcent_rand/100
self.x = [
n*np.random.uniform(low=1-pcent_decimal, high=1+pcent_decimal)
for n in np.linspace(3, 9, self.num_points)
]
self.y = [
n*np.random.uniform(low=1-pcent_decimal, high=1+pcent_decimal)
for n in np.linspace(3, 9, self.num_points)
]
self.redraw_slope()

def redraw_slope(self):
"""
Recompute slope line and redraw whole plot

Called whenever the slope changes.
"""
a = np.linspace(0, 9, self.num_points)
b = [(self.slope * n) for n in a]

self.output_widget.clear_output(wait=True)
with self.output_widget as f:
plt.figure(figsize=(9, 9), dpi=80)
plt.ylim(ymax=max(self.y)+1)
plt.xlim(xmax=max(self.x)+1)

plt.scatter(self.x, self.y)
plt.plot(a, b)
plt.show()

app = LinRegressDisplay()
app.container # actually display the widget

最后一点,当您移动 slider 时,动画仍然有点不和谐。为了更好的交互性,我建议查看 bqplot .特别是,Chakri Cherukuri 有一个很棒的 example of linear regression这与您正在尝试做的有点相似。

关于python - 在 Jupyter - Python 中有 2 个 Ipywidgets 作用于一个 matplotlib 图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52238567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com