Bokeh Plots Not Rendering In Streamlit on Azure Platform

Hi everyone, hopefully someone can help me solve this problem:

I’ve designed a series of plots using Bokeh that I am embedding into a streamlit app that is run in a docker container on an MS Azure server. I initially developed the plots locally and they rendered as expected. I then used docker to create a container that I pushed to my Azure account and deployed a web app in the normal manner. When I access the app through the internet the plots that were rendered fine locally were no longer rendered in any form. The website appears to skip to the next line when the different display methods are called. I’ve repeated this in Edge browser on my MS work machine and Safari on my personal Macbook with neither rendering the figures as expected.

I prepared a very simple version of the app at https://hw3-11(dot)azurewebsites(dot)net that uses Bokeh to access the autompg data set and then plot some figures and then plots them using the bokeh.plotting figure. (I’ll leave the page up for a few days from 30 June 2021 before removing it) I ‘think’ being able to call the data set shows that bokeh is running correctly, though I’m not sure. I also double checked that it wasn’t a rendering option by using matplotlib to plot some random numbers and that it wasn’t numpy by using that to generate some arrays and plot some other things in matplotlib.

I’m using a docker file that a colleague of mine created for this purpose. I’m a scientist rather than an azure / docker engineer, and I’ve assumed that everything here is as it should be.

The docker file reads (unaligned):
**** BEGIN DOCKERFILE ****

FROM python:3.7-slim-buster
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get -y install gcc mono-cs && \
rm -rf /var/lib/apt/lists/*
COPY /app /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 8501
RUN mkdir -p ~/.streamlit
WORKDIR /app
ENTRYPOINT ["streamlit", "run"]
CMD["hw3.py"]

**** END DOCKERFILE ****

Requirements are as follows:
**** BEGIN requirements.txt ****

streamlit
bokeh
numpy 
matplotlib

**** END requirements.txt ****

This is a pretty bare bones example however I figured that a minimalist approach would show the errors more clearly.

I tried calling the plot using the bokeh_chart and the write methods to double check if there was a preferred method. Without writing out the entire python code, the calls to the bokeh figures are:

import streamlit as st
from bokeh.sampledata.autompg import autompg_clean as df_bk
from bokeh.plotting import figure

p = figure(title = 'Test Bokeh Plot')
p.scatter(x = 'displ', y = 'hp', source = df_bk) 
st.bokeh_chart(p)
st.write(p)

I won’t include the code for the matplotlib or numpy elements as they work as expected.

Thanks for your help!

Hi @Chris_R please edit your post to use code formatting so that the code is intelligible (either with the </> icon on the editing toolbar, or triple backtick ``` fences around the code blocks)

that’s done

@Chris_R is there a dedicated help forum for Streamlit? If so that might be a better place to ask. Streamlit is a separate project that is not maintained by anyone on the Bokeh team. I don’t have any experience with it, e.g., so I am afraid I can’t offer any specific guidance, just general suggestions such as checking the browser JS log for any error messagese. cc @MarcSkovMadsen in case has any pointers.

Hi Bryan. No worries. I’m not having any issues with other elements of streamlit. I’ve managed to render graphs using matplotlib and (since originally posting) altair. It feels like the issue is a weird interaction that bokeh is having with the way the server or docker container is set up hence posting here. I’m a beginner when it comes to server back-ends, etc, and was hoping there might be some more specialist advice available.

Well, the browser JS console and network debug tab are the places to start. I.e. is BokehJS being loaded? Are there explicit errors reported?

I grabbed this screenshot from the console. Useful? It doesn’t mean much to me except for the things in bright red probably are bad! It makes sense that it’s duplicated as I call the plot twice using different streamlit methods.

@Chris_R

Bokeh JS and python versions need to match identically.

I don’t know why they do not in your case as bokeh typically takes care of this automatically, but this is where you should focus, I think. (I use Anaconda to manage packages locally and procfiles to host to a platform as a service like Heroku and have never encountered this issue.)

Specifically, I believe the syncable property is new to bokeh 2.3.# and is not available in earlier versions, and that is probably why 2.0.0 bokeh JS is not able to handle it.

1 Like

That definitely the issue. I have no idea how Streamlit supplies BokehJS resources. Normally will Bokeh handle coordinating BokehJS itself, but Streamlit must be doing something different. If they have somehow pinned their output to only load BokehJS 2.0.0 then you will need to stick with (python) Bokeh 2.0.0 as well.

1 Like

If you search streamlits github for bokeh

Search · bokeh (github.com)

you will find for example something like

I don’t know if this is the cause. But I know users have been complaining about Bokeh not working in Streamlit a lot. Especially around times when Bokeh was upgraded.

The user experiences you cite seem relevant to this discourse topic.

Per above, BokehJS and python versions need to match exactly.

If Streamlit is locking down BokehJS to 2.0.0 as shown in your GitHub screen capture, then the user’s who want to use latest bokeh in combination with Streamlit need to pursue that with the Streamlit maintainers. I don’t think this is something that can be addressed in bokeh.

The best thing we might do right now is provide a better and more user-facing warning when this happens. Currently there is just a fairly hidden JS console log message that many users will not know to check.

We are getting closer to a time when using a newer BokehJS with an older Python Bokeh version might work reasonably in many cases. But BokehJS is still under active development with new features being added. So trying to use older BokehJS with newer Python Bokeh, potentially means trying to access features that don’t exist in the older BokehJS, which can’t be “fixed” even in principle (beyond failing more gracefully).