Hello,
I’m stuck at a point where I try to integrate my bokeh server app with Flask. I am using the GMapOptions library in bokeh to generate a visualization showing the distribution of my client data across a geographical area. I get the following error when I run the Flask app code,
TypeError: init() missing 2 required positional arguments: ‘google_api_key’ and ‘map_options’
``
I get the same message in the command prompt when I run the bokeh server app independently in the command prompt using the bokeh serve command, but the app runs nevertheless.
Here is my code for the visualization,
coding: utf-8
In[1]:
from bokeh.plotting import figure, output_file, show, gmap
from bokeh.models import *
from bokeh.io import output_notebook, curdoc
from bokeh.transform import factor_cmap
from bokeh.layouts import column, row
import pandas as pd
import numpy as np
import pyodbc
output_file(“gmap.html”)
parameters
server = ‘X.X.X.X\PQR’
db = ‘abc’
Create the connection
conn = pyodbc.connect(‘DRIVER={SQL Server};SERVER=’ + server + ‘;DATABASE=’ + db + ‘;Trusted_Connection=yes’)
map_options = GMapOptions(lat=37.686293, lng=-97.3614409, map_type=“roadmap”, zoom=13)
p = gmap(“My Google Maps API Key”, map_options, title=“Resolutions Clients”, plot_width=1000, plot_height=600)
sql = “”"
with CTE AS
(SELECT
CR.ClientID, CR.Latitude, CR.Longtitude
FROM
Company C LEFT JOIN ClientRegistration CR on C.CompanyID = CR.CompanyID
WHERE
C.CompanyID = 555 AND (CR.Latitude IS NOT NULL AND CR.Longtitude IS NOT NULL)
)
SELECT
C.ClientID, C.Latitude, C.Longtitude, CL.Sex
FROM
CTE C LEFT JOIN Clients CL on C.ClientID = CL.ClientID
“”"
df = pd.read_sql(sql, conn)
df[[‘Latitude’, ‘Longtitude’]] = df[[‘Latitude’, ‘Longtitude’]].apply(pd.to_numeric)
df[‘Sex’] = df[‘Sex’].astype(‘str’)
map_options = GMapOptions(lat=37.686293, lng=-97.3614409, map_type=“roadmap”, zoom=10)
p = gmap(“My Google Maps API Key”, map_options, title=“Resolutions Clients Genderwise”, plot_width=1000,
plot_height=600)
lat = df[‘Latitude’].tolist()
lon = df[‘Longtitude’].tolist()
sex = df[‘Sex’].tolist()
source = ColumnDataSource(
data=dict(latitude=lat,
longitude=lon,
gender=sex
)
)
color_mapper = CategoricalColorMapper(factors=[‘M’, ‘F’, ‘U’], palette=[‘Red’, ‘Blue’, ‘Green’])
p.circle(x=“longitude”, y=“latitude”, size=4, fill_alpha=0.9, source=source,
fill_color={‘field’: ‘gender’, ‘transform’: color_mapper},
line_color={‘field’: ‘gender’, ‘transform’: color_mapper})
x = np.linspace(0, 4 * np.pi, 100)
y = np.sin(x)
p.circle(x, y, legend=“Male”, color=“red”)
p.circle(x, 2 * y, legend=“Female”, color=“Blue”)
p.circle(x, 3 * y, legend=“Unknown”, color=“Green”)
def update():
# query db
curdoc().clear()
sql = “”"
with CTE AS
(SELECT
CR.ClientID, CR.Latitude, CR.Longtitude
FROM
Company C LEFT JOIN ClientRegistration CR on C.CompanyID = CR.CompanyID
WHERE
C.CompanyID = 555 AND (CR.Latitude IS NOT NULL AND CR.Longtitude IS NOT NULL)
)
SELECT
C.ClientID, C.Latitude, C.Longtitude,
CASE WHEN age > 0 AND age <= 15 THEN ‘Children’
WHEN age > 15 AND age <= 30 THEN ‘Young Adult’
WHEN age > 30 AND age <= 55 THEN ‘Adult’
WHEN age > 55 THEN ‘Senior Citizen’
END AS ‘Age_Group’
FROM
CTE C LEFT JOIN Clients CL on C.ClientID = CL.ClientID
“”"
df = pd.read_sql(sql, conn)
df[['Latitude', 'Longtitude']] = df[['Latitude', 'Longtitude']].apply(pd.to_numeric)
df['Age_Group'] = df['Age_Group'].astype('str')
df['Latitude'].median()
df['Longtitude'].median()
map_options = GMapOptions(lat=37.686293, lng=-97.3614409, map_type="roadmap", zoom=10)
p = gmap("My Google Maps API Key", map_options, title="Resolutions Clients Age wise",
plot_width=1000, plot_height=600)
lat = df['Latitude'].tolist()
lon = df['Longtitude'].tolist()
age = df['Age_Group'].tolist()
source = ColumnDataSource(
data=dict(latitude=lat,
longitude=lon,
age_Group=age
)
)
color_mapper = CategoricalColorMapper(factors=['Children', 'Young Adult', 'Adult', 'Senior Citizen'],
palette=['Red', 'Blue', 'Green', 'Yellow'])
p.add_tools(LassoSelectTool())
p.add_tools(ZoomInTool())
p.add_tools(ZoomOutTool())
p.circle(x="longitude", y="latitude", size=4, fill_alpha=0.9, source=source,
fill_color={'field': 'age_Group', 'transform': color_mapper},
line_color={'field': 'age_Group', 'transform': color_mapper})
x = np.linspace(0, 4 * np.pi, 100)
y = np.sin(x)
p.circle(x, y, legend="Children : Age <= 15", color="red")
p.circle(x, 2 * y, legend="Young Adult : 30 >= Age > 15", color="Blue")
p.circle(x, 3 * y, legend="Adult : 55 >= Age > 30 ", color="Green")
p.circle(x, 4 * y, legend="Senior Citizen : Age > 55", color="Yellow")
curdoc().add_root(row(button1, button2))
curdoc().add_root(column(p))
def update1():
# query db
curdoc().clear()
sql = “”"
with CTE AS
(SELECT
CR.ClientID, CR.Latitude, CR.Longtitude
FROM
Company C LEFT JOIN ClientRegistration CR on C.CompanyID = CR.CompanyID
WHERE
C.CompanyID = 555 AND (CR.Latitude IS NOT NULL AND CR.Longtitude IS NOT NULL)
)
SELECT
C.ClientID, C.Latitude, C.Longtitude, CL.Sex
FROM
CTE C LEFT JOIN Clients CL on C.ClientID = CL.ClientID
“”"
df = pd.read_sql(sql, conn)
df[['Latitude', 'Longtitude']] = df[['Latitude', 'Longtitude']].apply(pd.to_numeric)
df['Sex'] = df['Sex'].astype('str')
map_options = GMapOptions(lat=37.686293, lng=-97.3614409, map_type="roadmap", zoom=10)
p = gmap("My Google Maps API Key", map_options, title="Resolutions Clients Genderwise",
plot_width=1000,
plot_height=600)
lat = df['Latitude'].tolist()
lon = df['Longtitude'].tolist()
sex = df['Sex'].tolist()
source = ColumnDataSource(
data=dict(latitude=lat,
longitude=lon,
gender=sex
)
)
color_mapper = CategoricalColorMapper(factors=['M', 'F', 'U'], palette=['Red', 'Blue', 'Green'])
p.circle(x="longitude", y="latitude", size=4, fill_alpha=0.9, source=source,
fill_color={'field': 'gender', 'transform': color_mapper},
line_color={'field': 'gender', 'transform': color_mapper})
x = np.linspace(0, 4 * np.pi, 100)
y = np.sin(x)
p.circle(x, y, legend="Male", color="red")
p.circle(x, 2 * y, legend="Female", color="Blue")
p.circle(x, 3 * y, legend="Unknown", color="Green")
curdoc().add_root(row(button1, button2))
curdoc().add_root(column(p))
add a button widget and configure with the call back
button1 = Button(label=“Gender”)
button2 = Button(label=“Age”)
button1.on_click(update1)
button2.on_click(update)
put the button and plot in a layout and add to the document
curdoc().add_root(row(button1, button2))
curdoc().add_root(column(p))
Here is my app.py file
from flask import Flask, render_template
from bokeh.embed import autoload_static
from bokeh.client import pull_session
#instantiating the flask app
app = Flask(__name__)
#create the index page function
@app.route("/")
def index():
session = pull_session(url="http://localhost:5006/Button_test_update_version2")
bokeh_script = autoload_static(None, url="http://localhost:5006/Button_test_update_version2", session_id=session.id)
return render_template("index.html", bokeh_script=bokeh_script)
#run the app
if __name__ == "_main_":
Here is my index.html file,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ABC Visualization</title>
<link rel="stylesheet" href={{url_for('static', filename='css/main.css')}}>
</head>
<body>
<h1>ABC Visualization</h1>
<div>
{{bokeh_script|safe}}
</div>
</body>
</html>
Here is my main.css file,
h3{
color : olive;
}