Bokeh chart not visible in Heroku

This chart displays fine via bokeh server on my local browser, but on heroku it just opens a browser window without showing the chart. The log file doesn’t throw up any errors, so I think the Procfile and requirements.txt are fine. I know similar questions have been asked, and I have looked through those but still can’t work out what I am doing wrong. Can somebody help?

import pandas as pd

url = 'https://www.esri.cao.go.jp/en/stat/shouhi/shouhi2.xlsx'
cc = pd.read_excel(url, skiprows=5, usecols = 'A:P', index_col=0)
cc = cc.dropna()
cc.index = pd.to_datetime(cc.index, format = "%Y00%m%d")
unnamed = [col for col in cc if 'Unnamed' in col]#
cc.drop(columns=unnamed, inplace=True)
cc.rename_axis('Date', axis=0, inplace=True)

url = 'https://www.esri.cao.go.jp/en/stat/shouhi/shouhi3.xlsx'
px = pd.read_excel(url, skiprows=3, usecols = 'A:T', index_col=0)
px = px.dropna()
px.index = pd.to_datetime(px.index, format = "%Y00%m%d")
unnamed = [col for col in px if 'Unnamed' in col]#
px.drop(columns=unnamed, inplace=True)
px['Weighted average'] = (-5 * (px['低下する_▲5%以上']/(100 - px['分からない']))) + (-3.5 * (px['低下する_▲5%未満~▲2%以上']/(100 - px['分からない']))) + (-1 * (px['低下する_▲2%未満']/(100 - px['分からない']))) + (5 * (px['上昇する_5%以上']/(100 - px['分からない']))) + (3.5 * (px['上昇する_2%以上~5%未満']/(100 - px['分からない']))) + (1 * (px['上昇する_2%未満']/(100 - px['分からない']))) 
px.rename_axis('Date', axis=0, inplace=True)

cc_recent = pd.merge(px, cc, on='Date', how='left')

from bokeh.plotting import figure, curdoc
#from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
from bokeh.models import DatetimeTickFormatter, NumeralTickFormatter
from bokeh.models import LinearAxis, Range1d
from bokeh.layouts import column

source = ColumnDataSource(cc_recent)

p = figure(sizing_mode="stretch_both")

p.y_range = Range1d(20, 50) 
p.line(x='Date',
       y='component indicators of Consumer Confidence Index_Overall livelihood',
       source=source,
       color='red',
       legend_label='Consumer confidence, livelihood')

p.extra_y_ranges = {"right_axis": Range1d(5, 0)}
ax2 = LinearAxis(y_range_name = 'right_axis')

p.add_layout(ax2, 'right')
p.yaxis[1].axis_label_text_font_size = "15pt"


p.line(x='Date',
       y='Weighted average',
       source=source,
       color='blue',
       y_range_name = 'right_axis',
       legend_label="Consumer inflation expectations, inverted")

p.title.text = 'Japan, consumer confidence and inflation expectations'
p.title_location = "above"
p.title.text_font_size = "25px"
p.title.text_font_style = 'bold'

p.yaxis.formatter = NumeralTickFormatter(format="0,0")

p.xaxis.formatter = DatetimeTickFormatter(months="%b %Y")
p.legend.location = "bottom_left"
p.legend.label_text_font_size = '15pt'

curdoc().add_root(p)

Procfile
web: bokeh serve --port=$PORT --allow-websocket-origin=jp-consumer.herokuapp.com --address=0.0.0.0 --use-xheaders jp_cc_trial.py

Log

-----> Building on the Heroku-20 stack

-----> Determining which buildpack to use for this app

-----> Python app detected

-----> Using Python version specified in runtime.txt

-----> Installing python-3.8.12

-----> Installing pip 21.3.1, setuptools 57.5.0 and wheel 0.37.0

-----> Installing SQLite3

-----> Installing requirements with pip

       Collecting bokeh==2.4.2

         Downloading bokeh-2.4.2-py3-none-any.whl (18.5 MB)

       Collecting Jinja2==3.0.3

         Downloading Jinja2-3.0.3-py3-none-any.whl (133 kB)

       Collecting MarkupSafe==2.0.1

         Downloading MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (30 kB)

       Collecting numpy==1.21.4

         Downloading numpy-1.21.4-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (15.7 MB)

       Collecting packaging==21.3

         Downloading packaging-21.3-py3-none-any.whl (40 kB)

       Collecting pandas==1.3.5

         Downloading pandas-1.3.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.5 MB)

       Collecting Pillow==8.4.0

         Downloading Pillow-8.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB)

       Collecting pyparsing==3.0.6

         Downloading pyparsing-3.0.6-py3-none-any.whl (97 kB)

       Collecting python-dateutil==2.8.2

         Downloading python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)

       Collecting pytz==2021.3

         Downloading pytz-2021.3-py2.py3-none-any.whl (503 kB)

       Collecting PyYAML==6.0

         Downloading PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (701 kB)

       Collecting requests==2.26.0

         Downloading requests-2.26.0-py2.py3-none-any.whl (62 kB)

       Collecting six==1.16.0

         Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)

       Collecting tornado==6.1

         Downloading tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl (427 kB)

       Collecting typing_extensions==4.0.1

         Downloading typing_extensions-4.0.1-py3-none-any.whl (22 kB)

       Collecting charset-normalizer~=2.0.0

         Downloading charset_normalizer-2.0.9-py3-none-any.whl (39 kB)

       Collecting idna<4,>=2.5

         Downloading idna-3.3-py3-none-any.whl (61 kB)

       Collecting certifi>=2017.4.17

         Downloading certifi-2021.10.8-py2.py3-none-any.whl (149 kB)

       Collecting urllib3<1.27,>=1.21.1

         Downloading urllib3-1.26.7-py2.py3-none-any.whl (138 kB)

       Installing collected packages: six, pyparsing, MarkupSafe, urllib3, typing-extensions, tornado, PyYAML, pytz, python-dateutil, Pillow, packaging, numpy, Jinja2, idna, charset-normalizer, certifi, requests, pandas, bokeh

       Successfully installed Jinja2-3.0.3 MarkupSafe-2.0.1 Pillow-8.4.0 PyYAML-6.0 bokeh-2.4.2 certifi-2021.10.8 charset-normalizer-2.0.9 idna-3.3 numpy-1.21.4 packaging-21.3 pandas-1.3.5 pyparsing-3.0.6 python-dateutil-2.8.2 pytz-2021.3 requests-2.26.0 six-1.16.0 tornado-6.1 typing-extensions-4.0.1 urllib3-1.26.7

-----> Discovering process types

       Procfile declares types -> web

-----> Compressing...

       Done: 107.1M

-----> Launching...

       Released v3

       https://jp-consumer.herokuapp.com/ deployed to Heroku

Build finished

@paul_c

I use bokeh server on Heroku for my apps without problems. My apps are quite a bit different in the details – leveraging nginx for load balancing, flask for embedding and user management, etc., but the core bokeh/panel server logic should be similar to your use case.

Regarding the following the following statement … are you saying the build log that you included in the post shows no errors? If so, what about the actual server logs from bokeh. These should be reflected the Heroku dashboard and will show any status and error messages when you spin up the server and when clients connect to it to use the functionality?

Does the JavaScript console in your web browser show any useful information or error messages for the specific client session?

1 Like

Thanks v much for pointing me in the right direction.

For other beginners out there, I was looking at the “View build log” in heroku, which was showing no errors. But heroku logs in terminal showed I was still missing a python package in my requirements.txt.