为什么Bokeh RadiButtonGroup在我的Django应用程序中不起作用?

vlurs2pr  于 2022-09-18  发布在  Java
关注(0)|答案(1)|浏览(151)

i'm trying to develope a webapp for my master thesis. I used Bokeh to do interactive plot, and i embedded it in a django app. The problem is that i don't manage to do something with js_on_change or js_on_click of radiobuttongroup.

This is my view:

def DTA_webAPP(request):
context={}
result = None
imps = pd.DataFrame(columns=["1","2","3","4","5"]) # i need this to avoid problem in create_grid in plotting.py
dta = pd.DataFrame(columns = ["3","4"])
fig = myfig(imps,dta)
script,div = components(fig.layout) 
form = DTAselection(request.POST,request.FILES)
if request.method == 'POST' and "Compute" in request.POST:
    if form.is_valid():
        data = pd.read_csv(request.FILES["ImportData"],sep = "\t",  skiprows = [1,2])
        imps, dta = main(data, form['method_of_discretization'].value(),float(form['regularization_parameter'].value()), int(form['regularization_order'].value()), int(form['number_of_point'].value()), form['col_selection'].value())
        fig = myfig(imps, dta)
        script, div = components(fig.layout)
        imps.to_csv("result_imps.csv", index = False)
        dta.to_csv("result_dta.csv", index = False)
        result = "Ok, boy"
context =  {'form': form, 'script':script, 'div':div, "result":result}
return HttpResponse(render(request, "dta_webapp.html", context))

the figure is created in the class myfig.

This is my class myfig:

LABELS = ["IMPS","REAL RESIDUALS", "IMAG RESIDUALS"]
 class myfig(object):
    def __init__(self, df_data, df_dta):
    self.df_data = df_data
    self.df_dta = df_dta

    self.radio_button_group = RadioButtonGroup(labels=LABELS, active=0)
    self.source = None
    self.plot = self.create_grid()
    self.radio_button_group.js_on_change('active', CustomJS(args=
            dict(s=self.source,
                p = self.plot.children[0],
                x = self.df_data.columns[1], 
                y = self.df_data.columns[2],
                ),
            code="""
                console.log('radio_button_group: active=' + this.active, this.toString());
                const s1 = new Bokeh.ColumnDataSource({data : {x: [3,4,5,6,6] , y:[3,4,5,6,4] }  }) ;
                s = s1;
                s.change.emit();
                 """))
    self.layout = layout([
           [self.radio_button_group],
            [self.plot],
       ])

def create_grid(self):
    plot_data=figure(title= "IMPS", x_axis_label="Y'",  y_axis_label="Y''")
    source_data = ColumnDataSource(data = self.df_data)
    vec_size = np.arange(0,len(self.df_data.columns), 1,dtype=int)
    #columns = int(len(self.df_data.columns)/(len(self.df_data.columns)/5)))
    data_to_plot = vec_size.reshape(int(len(self.df_data.columns)/5),5)
    palettes_ = RdYlGn[vec_size.size] 
    self.source = source_data
    for number, fix_voltage in enumerate(data_to_plot):
        plot_data.circle(x = self.df_data.columns[fix_voltage[1]], y = self.df_data.columns[fix_voltage[2]], source = self.source,color=palettes_[number])
        plot_data.line(x = self.df_data.columns[fix_voltage[3]], y = self.df_data.columns[fix_voltage[4]], source = self.source, color = palettes_[number], line_dash = "dashed")
    #plot_data.add_layout(LinearAxis(y_range_name="Y''"), 'left')
    #plot_data.add_layout(LinearAxis(x_range_name="Y'"), 'below')
    freq = "@" + self.df_data.columns[0]
    TOOLTIPS=[
        ("freq" ,freq),
        ("x", "$x"),
        ("y", "$y"),]
    plot_data.add_tools(HoverTool(tooltips=TOOLTIPS))
    plot_dta = figure(title="DTA result",  x_axis_type="log",x_axis_label="Time (s)",  y_axis_label="DTA (V^-1)")
    source_dta = ColumnDataSource(data = self.df_dta)

    vec_size = np.arange(0,len(self.df_dta.columns), 1,dtype=int)
    data_to_plot = vec_size.reshape(int(len(self.df_dta.columns)/2),2)
    for number, fix_voltage in enumerate(data_to_plot):
        plot_dta.line(x = self.df_dta.columns[fix_voltage[0]], y = self.df_dta.columns[fix_voltage[1]], source = source_dta,color = palettes_[number],)
    freq ="@" + self.df_data.columns[0] 
    TOOLTIPS=[
        ("tau", "$x"),
        ("DTA", "$y"),]
    plot_dta.add_tools(HoverTool(tooltips=TOOLTIPS))
    grid = row(plot_data, plot_dta)
    return grid

I put this is in my html head:

<!-- BOKEH DEPENDENCIES -->
<link href="http://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.css" rel="stylesheet" type="text/css"> 
<link href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.css" rel=”stylesheet” type=”text/css”>

and this at the very end of my html:

</body>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-api-2.4.2.min.js"></script>
{{ script |safe}}  
</html>

I'm using Bokeh==2.4.2. In the css sources i put 1.4.0 version since with 2.4.2 as version rise an error. GET https://cdn.pydata.org/bokeh/release/bokeh-2.4.2.min.css net::ERR_ABORTED 403 , but i think write previous version of css is not a problem in the question i posed.

The warning i got in the compiler are the following: I tryed a lot of stuff but my figure never update if i change the radio active button. The only thing i managed to obtain is a creation of new figure with a Bokeh.Plotting.show(plot) in the js callback, but this is not what i want. I want to change radically in xaxis and yaxis name, title, and data the two figures in the self.plot, created by the method create_grid(). This method return a row(figure1, figure2) that is stored in self.plot. I want to take control on figure1 figure2 by the callback . I tried to update the ColumnDataSource but nothing, i tried to change all the plot and do plot.change.emit() but nothing. What is wrong in my approach?

t9aqgxwy

t9aqgxwy1#

对于最新版本的bokeh的css资源,您可以使用bokeh.resource来获取依赖项。而不是这样:

<!-- BOKEH DEPENDENCIES -->
<link href="http://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.css" rel="stylesheet" type="text/css"> 
<link href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.css" rel=”stylesheet” type=”text/css”>

在您的HTML头部分使用以下内容:

{{ resources|safe }}

并在您的视图中进行以下更改:

from bokeh.resources import CDN

context =  {'form': form, 'script':script, 'div':div, "result":result, 'resources':CDN.render()}

这将为您提供与您的bokeh版本兼容的依赖项。至于单选按钮部分,我仍然不确定你想做什么,以及正在发生什么。

相关问题