Search code examples
python-3.xflaskcallbackbokehgcloud

Deploy bokeh with jscallback in Flask(gcloud)



I am building a bokeh webapp, so far so good. Though I have reached a problem that I have no idea where to start to fix it.
I have done a chart with a js_callback, locally it works just fine, once I try to deploy it though everything else deploys fine, except the plot with the js_callback. Any help will much appreciated.
Thanks in advance.

data data1
webapp so far

app.py

from flask import Flask, render_template, request
from bokeh.embed import components
from plots1 import houseStockPlot, vacantPlot, Transactions, NewRegistered, nonOccupiers, pie_chart
from tabs import maps, ageGroup, popOverall, naturalincrease, netMigration, mapDev
from flask_bootstrap import Bootstrap

@app.route('/bokeh')
def bokeh():
    script, div = components(houseStockPlot())
    script1, div1 = components(vacantPlot())
    script2, div2 = components(Transactions())
    script3, div3 = components(NewRegistered())
    script4, div4 = components(nonOccupiers())
    script5, div5 = components(pie_chart())
    script6, div6 = components(maps())
    script7, div7 = components(ageGroup())
    script8, div8 = components(popOverall())
    script9, div9 = components(naturalincrease())
    script10, div10 = components(netMigration())
    script11, div11 = components(mapDev())


    return render_template('bokeh.html', script=script, div=div, script1=script1,
    div1=div1, script2=script2, div2=div2, script3= script3, div3=div3, script4=script4, div4=div4,
    script5=script5, div5=div5, script6=script6, div6=div6, script7=script7, div7=div7, script8=script8, div8=div8,
    script9=script9, div9=div9, script10=script10, div10=div10, script11=script11, div11=div11)

.html file

<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-1.3.4.min.js"></script>
<script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.3.4.min.js"></script>
<link href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.3.4.min.css" rel="stylesheet" type="text/css">
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-1.3.4.min.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-1.3.4.min.js" type="text/css" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/article.css') }}"  type="text/css" >
<link href="/static/styles1.css" rel="stylesheet">



{{ script|safe }}
{{ script1|safe }}
{{ script2|safe }}
{{ script3|safe }}
{{ script4|safe }}
{{ script5|safe }}
{{ script6|safe }}
{{ script7|safe }}
{{ script8|safe }}
{{ script9|safe }}
{{ script10|safe }}
{{ script11|safe }}

</p>
<center>
    <div class='bokeh'>
        {{ div8|safe }} 
    </div>
</center>

plot.py

def popOverall():

    df1 = pd.read_csv('BokehApp/Data/ageGroupYear.csv', delimiter=',')
    df1['color'] = viridis(len(df1.index))
    df1['2009.'] = df1['2009'].values

    source1 = ColumnDataSource(data=dict(df1))


    p1 = figure(x_range=list(df1['Age Groups'].values), plot_height=300, plot_width=500,title='Irish Population Breakdown by Age Group',
                tools='pan, wheel_zoom, box_zoom, reset', toolbar_location='right')
    p1.vbar(x='Age Groups', top='2009.', width=0.5, source=source1, color='color')

    #plot style
    p1.xaxis.major_label_orientation = 45
    
    #p1.grid.grid_line_color=None
    p1.outline_line_color=None
    p1.axis.major_label_text_font_style = 'bold'
    #p1.toolbar.autohide = True
    p1.grid.grid_line_alpha = 0.6
    p1.grid.grid_line_dash = 'dotted'
    p1.grid.grid_line_dash_offset = 5
    p1.grid.grid_line_width = 2

    hoverp1 = HoverTool()
    hoverp1.tooltips=[('Group Population', '@2009')]
    p1.add_tools(hoverp1)


    tick_labels_p1 = {'100':'100K','200':'200K','300':'300K','400':'400K'}
    p1.yaxis.major_label_overrides = tick_labels_p1
    

    df = pd.read_csv('BokehApp/Data/OverAll.csv', delimiter=',', index_col='Year')
    df['color'] = viridis(len(df.index))


    xrange = (2009,2018)
    xrange
    yrange = (df['Population'].min(), df['Population'].max())

    source = ColumnDataSource(df)


    p = figure(plot_height=300, plot_width=400,title='Irish Population Growth by Year',
               y_range=Range1d(*yrange),tools='pan, wheel_zoom, box_zoom, reset', toolbar_location='above')

    p.vbar(x='Year', top='Population', source=source, width=0.5, color='color')
    
    #plot style
    #p.xaxis.major_label_orientation = 45
    #p.grid.grid_line_color=None
    #p.x_range.start = 2009
    p.x_range.end = 2018.5
    p.grid.grid_line_alpha = 0.6
    p.y_range.start = 4500
    p.y_range.end = df['Population'].max()*1.003
    p.outline_line_color=None
    p.axis.major_label_text_font_style = 'bold'
    p.toolbar.autohide = True
    p.grid.grid_line_dash = 'dotted'
    p.grid.grid_line_dash_offset = 5
    p.grid.grid_line_width = 2
    p.toolbar.autohide=True
    #p.yaxis.axis_line_color = None

    hoverp = HoverTool()
    hoverp.tooltips=[('Year','@Year'),('Population', '@Population{int}')]
    p.add_tools(hoverp)


    tick_labels_p = {'4500':'450M','4550':'455M','4600':'460M','4650':'465M','4700':'470M','4750':'475M', '4800':'480M','4850':'485M'}
    p.yaxis.major_label_overrides = tick_labels_p


    select = Select(title="Year:", align='center', value='2009.', width=60, height=25, options=['2009','2010', '2011', '2012','2013','2014','2015','2016','2017','2018'])
    p1.title.text = 'Irish Population by Age Group ' +  str(select.value)

    callback = CustomJS(args={'source':source1, 'title':p1.title},code="""
            console.log(' changed selected option', cb_obj.value);

            var data = source.data;
            title.text = 'Irish Population by Age Group ' + cb_obj.value

            // allocate column
            data['2009.'] = data[cb_obj.value];



            // register the change 
            source.change.emit()""")

    select.callback = callback


    layout = row(p,select, p1, margin=5) 
    return layout

Solution

  • In case something come across to a similar problem. I updated bokeh to the latest version, readjusted all the deprecated models, I still didn't managed to deploy the plot with CustomJS, not even make it works locally(it was working before), anyhow I replaced my CDNs and it worked both locally and with gunicorn. Thanks @bigreddot for help.

    <script src="https://cdn.bokeh.org/bokeh/release/bokeh-2.1.1.min.js"></script>
    <script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.1.1.min.js"></script>
    <script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.1.1.min.js"></script>