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

使用参数值的滑块创建连续均匀分布的交互式绘图

如何解决使用参数值的滑块创建连续均匀分布的交互式绘图

如何使用 python 创建 Continuous Uniform Distribution 的 pdf 和 cdf 的交互式绘图?

uniform distribution

我想要交互式滑块,我可以用它来调整分布的参数。

这有助于更好地了解此分布对其不同参数值的行为。

解决方法

1.最简单的方法是使用 scipy.stats.uniform() 获取分布的 pdf 和 cdf,然后使用 pn.interact() 获取参数的交互式滑块:

# import libraries
from scipy import stats
import pandas as pd
import hvplot.pandas
import panel as pn
pn.extension()
import panel.widgets as pnw
import holoviews as hv
hv.extension('bokeh')


# define pdf and cdf for cont uniform distr and return plots
def get_interactive_plot_cont_uniform(loc=1,scale=5):
    continuous_uniform = stats.uniform(loc=loc,scale=scale)
    
    x_values = np.linspace(0,10,num=1000)
    fx_values = continuous_uniform.pdf(x_values)
    Fx_values = continuous_uniform.cdf(x_values)
    
    interactive_plot = (
        hv.Curve((x_values,fx_values),label='PDF') 
        + hv.Curve((x_values,Fx_values),label='CDF'))
    return interactive_plot

# use pn.interact() to get interactive sliders 
# and define the sliders yourself for more flexibility
pn.interact(
    get_interactive_plot_cont_uniform,loc=pnw.FloatSlider(
       name='Value for loc',value=1.,start=0,step=0.5,end=10),scale=pnw.FloatSlider(
       name='Value for scale',value=5.,)

产生的带有滑块的交互式绘图:

interactive plot with sliders of continuous uniform distribution

2.一个更广泛、更灵活的例子,它允许更直观地设置参数 a 和 b:

# create sliders to adjust parameter a and b
param_a = pnw.FloatSlider(name='Value for parameter a',end=10)
param_b = pnw.FloatSlider(name='Value for parameter b',value=6.,end=10)

# get interactivity by using following decorator
@pn.depends(param_a,param_b)
def get_interactive_cont_uniform(param_a,param_b):
    
    # define the uniform distribution
    # scale in scipy.stats.uniform is b - a
    loc = param_a
    scale = param_b - param_a
    continuous_uniform = stats.uniform(loc=loc,scale=scale)

    # calculate x and y values for pdf and cdf and put in dataframe
    x_values = np.linspace(0,num=1000)
    fx_values = continuous_uniform.pdf(x_values)
    Fx_values = continuous_uniform.cdf(x_values)

    df = pd.DataFrame({
        'x': x_values,'f(x)': fx_values,'F(x)': Fx_values,})

    # create pdf and cdf plot
    pdf_plot = df.hvplot.line(
        x='x',y='f(x)',ylim=(0,1.02),ylabel='f(x) - pdf values',xlabel='',title=f'pdf where a={param_a} and b={param_b}',height=225,).opts(fontscale=1.25)
    
    cdf_plot = df.hvplot.line(
        x='x',y='F(x)',ylabel='F(x) - cdf values',title=f'cdf where a={param_a} and b={param_b}',).opts(fontscale=1.25)
    
    return (pdf_plot + cdf_plot).cols(1)

# use pyviz panel to get a nice view of sliders and the plots
pn.Column(
    pn.pane.Markdown("## Continuous Uniform Distribution"),pn.Row(param_a,param_b),pn.Row(get_interactive_cont_uniform)
)
,

要建立在另一个答案的基础上,您还可以使用 panel 实现的面向类的方法。这是我最喜欢的方法,因为它使您的代码保持良好和模块化。此外,它直接通过 bokeh 绘图,而不是通过 holoviews (我个人一般对此持怀疑态度)。使用 bokeh 而不是 holoviews 可以让您更好地控制您的情节,但对于这些目的,您选择哪条路线并不重要。

此代码段在笔记本中工作,但可以通过将 .show() 方法的调用更改为 .servable() 并使用以下命令从命令行/终端运行脚本来适应脚本格式:panel serve file.py --show

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
import panel as pn
import param
from scipy import stats

class UniformViewer(param.Parameterized):
    a = param.Number(1,bounds=(0,15),step=.5)
    b = param.Number(4,step=.5,inclusive_bounds=(False,True))
    
    def __init__(self,**params):
        super().__init__(**params)
        
        # Initialize 2 plots with common arguments
        plot_kwargs = {
            "height": 250,"width": 250,"y_range": (-.1,1.1)
        }
        self.p_pdf = figure(title="PDF",**plot_kwargs)
        self.p_cdf = figure(title="CDF",**plot_kwargs)
        
        # Calculate range of data based on parameter bounds
        a_min,a_max = self.param.a.bounds
        b_min,b_max = self.param.b.bounds
        
        # Create x-values for pdf/cdf calculations
        x_min,x_max = min(a_min,b_min),max(a_max,b_max)
        self.x = np.linspace(x_min,x_max,1000)
        
        # store x values in our CDS since they won't change
        self.cds = ColumnDataSource({"x": self.x}) 
        self.update_cds() # Populate cdf/pdf values into the CDS before plotting
        
        # Draw our pdf and cdf on their respective figures
        self.p_pdf.line(x="x",y="pdf",source=self.cds)
        self.p_cdf.line(x="x",y="cdf",source=self.cds)
        
    # Add callback that executes anytime self.a or self.b changes
    @param.depends("a","b",watch=True)
    def update_cds(self):
        # Calcualte the uniform distribution using
        # self.a as the left endpoint and self.b as the right endpoint
        uniform_dist = stats.uniform(loc=self.a,scale=self.b-self.a)
        
        self.cds.data.update({
            "pdf": uniform_dist.pdf(self.x),"cdf": uniform_dist.cdf(self.x)
        })
    
    def view(self):
        return pn.Row(self.p_pdf,self.p_cdf)
    
interactive_plot = UniformViewer()

pn.Column(interactive_plot,interactive_plot.view()).show()

enter image description here

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

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?