I've written a python 3 code using Bokeh. With this code you can learn howto to plot math functions and a scatter plot with regression linear functions in a webpage.
The target is how to plot discontinuous functions, linear regression problems in a webpage, and how to separates the differents plots in a webpage using Bokeh. A good looking for the webpage is not the target.
Another important target is how to plot linear regression using numpy and scipy.
Defining my own bokeh configurations with some functions in a python file:
# -*- coding: utf-8 -*-
"""
Created on Sat May 30 08:57:38 2015
@author: Tobal
"""
__author__ = 'Tobal'
__email__ = '[email protected]'
__version__ = '1.0'
from bokeh.embed import components
regression_line = lambda x, slope, intercept: slope * x + intercept
def plot_settings(my_figure, title, xlabel, ylabel, pwidth, pheight, xrange, yrange, legend_space):
my_figure.title = title
my_figure.xaxis.axis_label = xlabel
my_figure.yaxis.axis_label = ylabel
my_figure.plot_width = pwidth
my_figure.plot_height = pheight
my_figure.x_range = xrange
my_figure.y_range = yrange
my_figure.legend.legend_spacing = legend_space
def my_function_plot(my_figure, x, y, legend, line_width, color, alpha):
my_figure.line(
x, y, legend=legend, line_width=line_width, color=color, alpha=alpha)
def asymptote(my_figure, x, y, legend, line_width, line_dash, color, alpha):
my_figure.line(x, y, legend=legend, line_width=line_width,
line_dash=line_dash, color=color, alpha=alpha)
def scatter_plot(my_figure, x, y, legend, line_width, color, alpha):
my_figure.circle(
x, y, legend=legend, line_width=line_width, color=color, alpha=alpha)
def circles_plot(my_figure, x, y, legend, line_width, color, fill_color, alpha):
my_figure.circle(
x, y, legend=legend, line_width=line_width, color=color, fill_color=fill_color, alpha=alpha)
def regr_segment(my_figure, x0, y0, x1, y1, legend, line_width, color, alpha):
my_figure.segment(
x0, y0, x1, y1, legend=legend, line_width=line_width, color=color, alpha=alpha)
def plot_html(myfigure, myfilejs, myclass):
script, div = components(myfigure)
with open(myfilejs, 'wt') as myfile:
script = script.replace('</script>', '')
script = script.replace('<script type="text/javascript">', '')
div = div.replace(
div, 'document.querySelector(".' + myclass + '").innerHTML = ' + "'" + div + "'")
print(script + div, file=myfile)
Now in a different python file I define how to plot an equilateral function, the floor function and the linear regression example using the code above.
# -*- coding: utf-8 -*-
"""
Created on Sat May 30 08:57:38 2015
@author: Tobal
"""
__author__ = 'Tobal'
__email__ = '[email protected]'
__version__ = '1.0'
from bokeh.plotting import figure
from bokeh.models import Range1d
from mybokeh import *
import numpy as np
from scipy import stats
f = lambda x: 1. / x
x = np.linspace(-5.0, 5.0, 200)
pos = np.where(np.abs(np.diff(f(x))) >= 10.0)[0]
x = np.insert(x, pos, np.nan)
TOOLS = 'pan, wheel_zoom, box_zoom, reset, save, help'
p = figure(tools=TOOLS)
plot_settings(p, 'Rational Function', 'x', 'f(x)', 500, 500, Range1d(-5, 5), Range1d(-5, 5), 10)
my_function_plot(p, x, f(x), 'f(x)=1/x', 2, 'firebrick', 0.75)
asymptote(p, np.arange(-5, 6), 0, 'y=0', 2, [6, 4], 'navy', 0.75)
asymptote(p, 0, np.arange(-5, 6), 'x=0', 2, [6, 4], 'red', 0.75)
samplex = np.array([2, 2, 3, 3, 4, 4, 4, 5, 5, 5])
sampley = np.array([1, 2, 2, 3, 3, 4, 5, 4, 5, 6])
slope, intercept, r_value, p_value, std_err = stats.linregress(
samplex, sampley)
r_squared = r_value ** 2
slopex, interceptx, r_valuex, p_valuex, std_errx = stats.linregress(
sampley, samplex)
r_squaredx = r_valuex ** 2
p1 = figure(tools=TOOLS)
plot_settings(p1, 'Linear Regression', 'Number Of Rooms', 'Number Of Persons', 500, 500, Range1d(0, 7), Range1d(0, 8), 10)
scatter_plot(p1, samplex, sampley, 'Rooms / People', 2, 'firebrick', 0.75)
legend1 = 'y = {0:2.1f} + {1:2.3f}(x-{2:2.1f})'.format(
np.mean(sampley), slope, np.mean(samplex))
legend2 = 'x = {0:2.1f} + {1:2.3f}(y-{2:2.1f})'.format(
np.mean(samplex), slopex, np.mean(sampley))
regr_segment(p1, samplex[0], regression_line(samplex[0], slope, intercept), samplex[-1], regression_line(samplex[-1], slope, intercept), legend1, 2, 'navy', 0.75)
regr_segment(p1, sampley[0], regression_line(sampley[0], slopex, interceptx), sampley[-1], regression_line(sampley[-1], slopex, interceptx), legend2, 2, 'green', 0.75)
p2 = figure(tools=TOOLS)
abcisa = np.linspace(-7.0, 7.0, 1000)
pos = np.where(np.abs(np.diff(np.floor(abcisa))) >= 1.0)[0] + 1
abcisa = np.insert(abcisa, pos, np.nan)
igual = np.arange(-7, 7, 1)
igual_mas_uno = igual + np.ones(7 - (-7), np.int)
plot_settings(p2, 'Floor Function', 'x', 'y', 500, 500, Range1d(-7, 7), Range1d(-7, 8), 10)
my_function_plot(p2, abcisa, np.floor(abcisa), 'f(x)', 2, 'blue', 0.75)
circles_plot(p2, igual, igual, '', 2, 'blue', 'blue', 0.75)
circles_plot(p2, igual_mas_uno, igual, '', 2, 'blue', 'white', 0.75)
plot_html(p, './js/figures.js', 'myplot')
plot_html(p1, './js/figures1.js', 'myplot1')
plot_html(p2, './js/figures2.js', 'myplot2')
The code creates 3 independent javascripts files, one file for each plot.
Finally the html5 code, using Mathjax
<!DOCTYPE html>
<html lang='es'>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name='apple-mobile-web-app-capable' content='yes'>
<title>Tests With Bokeh</title>
<link rel='shortcut icon' href='./img/favicon.ico'/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<link href='./css/bokeh.min.css' rel='stylesheet'>
<link href='./css/styles.css' rel='stylesheet'>
</head>
<body>
<h1> Equilateral Hyperbola And Linear Regression</h1>
<section class='myplot'></section>
<p class='latex_figure_caption'>
The function is $f(x)=\frac{1}{x}$
</p>
<section class='myplot1'></section>
<div class="table-responsive">
<table class="table table-hover table-bordered table-condensed">
<thead>
<th class="text-center"> Flats Problem</th>
<th class="text-center">$\mu$</th>
<th class="text-center">Slope</th>
<th class="text-center">$R^2\, ( \% )$</th>
<th class="text-center">CorrCoef ( % )</th>
<th class="text-center">p-value</th>
</thead>
<tbody>
<tr class="text-center">
<th class="text-center">Number Of Rooms</th>
<td>3.7</td>
<td>$m_{xy}=0.644$</td>
<td>77.23 %</td>
<td>87.87 %</td>
<td>0.00081</td>
</tr>
<tr class="text-center">
<th class="text-center">Number Of Persons</th>
<td>3.5</td>
<td>$m_{yx}=1.198$</td>
<td>77.23 %</td>
<td>87.87 %</td>
<td>0.00081</td>
</tr>
</tbody>
</table>
</div>
<h2>Plotting The Floor Function</h2>
<section class='myplot2'></section>
<p class="latex_figure_caption">
$f(x)=\lfloor x \rfloor$
</p>
<script src='./js/jquery.js'></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src='./js/bokeh.min.js'></script>
<script src='./js/figures.js'></script>
<script src='./js/figures1.js'></script>
<script src='./js/figures2.js'></script>
<script type='text/x-mathjax-config'>
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'],['\\(','\\)']]}
});
</script>
<script type='text/javascript' src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML-full'></script>
</body>
</html>
I've used Anaconda for Bokeh, and Mathjax for LateX expressions.
All the code is available in my own GitHub repository, including the css file.
Link To The Code
I expect these real examples are useful for Bokeh Users, and the code is free to improve it, too.
Thanks and excuse my poor english.