I'm trying to modify the code from a Bokeh library plot. Link for it is here.
My goal is to have a different y-scale for the plots. I edited the make_plot
function and instead am copying the contents of that function to try and make the 2nd (upper-right) plot, using x and y2 columns instead of x and y columns as was used for the first (upper-left) plot.
I got this far:
from __future__ import print_function
import numpy as np
import pandas as pd
from bokeh.util.browser import view
from bokeh.document import Document
from bokeh.embed import file_html
from bokeh.layouts import column, gridplot
from bokeh.models import Circle, ColumnDataSource, Div, Grid, Line, LinearAxis, Plot, Range1d
from bokeh.resources import INLINE
raw_columns=[
[176.232, 2.212975, 176.232, 14088.2, 10.0, 7.46, 8.0, 6.58],
[177.487, 2.212190, 177.487, 14080.6, 8.0, 6.77, 8.0, 5.76],
[178.743, 2.211719, 178.743, 14057.6, 13.0, 12.74, 8.0, 7.71],
[180, 2.211562, 180, 14019.3, 7.11, 8.0, 8.84],
[181.257, 2.211719, 181.257, 14080.6, 11.0, 7.81, 8.0, 8.47],
[182.513, 2.212190, 182.513, 14057.6, 14.0, 8.84, 8.0, 7.04],
[183.768, 2.212975, 183.768, 14019.3, 5.0, 5.73, 8.0, 6.89]]
df = pd.DataFrame(data=raw_columns, columns=
['Ix','Iy','IIx','IIy','IIIx','IIIy','IVx','IVy'])
circles_source = ColumnDataSource(
data = dict(
xi = df['Ix'],
yi = df['Iy'],
xii = df['IIx'],
yii = df['IIy'],
xiii = df['IIIx'],
yiii = df['IIIy'],
xiv = df['IVx'],
yiv = df['IVy'],
)
)
x = np.linspace(176, 184, 100)
x1column = df['Ix'].values
y1column = df['Iy'].values
#y = 0.0000995532*x**2 - 0.0358391636*x + 5.4370863900
z = np.polyfit(x1column,y1column,2)
y = z[0]*x**2 + z[1]*x +z[2]
lines_source = ColumnDataSource(data=dict(x=x, y=y))
xdr = Range1d(start=176, end=184)
ydr = Range1d(start=2.2115, end=2.2135)
x2dr = Range1d(start=-0.12, end=0.12)
y2dr = Range1d(start=14000, end=14100)
x2column = df['IIx'].values
y2column = df['IIy'].values
z2 = np.polyfit(x1column,y2column,2)
y2 = z2[0]*x**2 + z2[1]*x +z2[2]
def make_plot(title, xname, yname):
plot = Plot(x_range=xdr, y_range=ydr, plot_width=400, plot_height=400,
background_fill_color='#efefef')
plot.title.text = title
xaxis = LinearAxis(axis_line_color=None)
plot.add_layout(xaxis, 'below')
yaxis = LinearAxis(axis_line_color=None)
plot.add_layout(yaxis, 'left')
plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
line = Line(x='x', y='y', line_color="#666699", line_width=2)
plot.add_glyph(lines_source, line)
circle = Circle(
x=xname, y=yname, size=12,
fill_color="#cc6633", line_color="#cc6633", fill_alpha=0.5
)
plot.add_glyph(circles_source, circle)
return plot
#where will this comment show up
I = make_plot('I', 'xi', 'yi')
#playing around starts here
plot = Plot(x_range=x2dr, y_range=y2dr, plot_width=400, plot_height=400,
background_fill_color='#efefef')
plot.title.text = 'd-d transition'
xaxis = LinearAxis(axis_line_color=None)
plot.add_layout(xaxis, 'below')
yaxis = LinearAxis(axis_line_color=None)
plot.add_layout(yaxis, 'left')
plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
lines_source = ColumnDataSource(data=dict(x=x, y=y2))
line = Line(x='x', y='y2', line_color="#666699", line_width=2)
plot.add_glyph(lines_source, line)
circle = Circle(
x='xii', y='yii', size=12,
fill_color="#cc6633", line_color="#cc6633", fill_alpha=0.5
)
plot.add_glyph(circles_source, circle)
II = plot
#playing around ends here
#II = make_plot('II', 'xii', 'yii')
III = make_plot('III', 'xiii', 'yiii')
IV = make_plot('IV', 'xiv', 'yiv')
grid = gridplot([[I, II], [III, IV]], toolbar_location=None)
div = Div(text="""
<h1>Anscombe's Quartet</h1>
<p>Anscombe's quartet is a collection of four small datasets that have nearly
identical simple descriptive statistics (mean, variance, correlation, and linear
regression lines), yet appear very different when graphed.
</p>
""")
doc = Document()
doc.add_root(column(div, grid, sizing_mode="scale_width"))
if __name__ == "__main__":
doc.validate()
filename = "anscombe.html"
with open(filename, "w") as f:
f.write(file_html(doc, INLINE, "Anscombe's Quartet"))
print("Wrote %s" % filename)
view(filename)
ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name. This could either be due to a misspelling or typo, or due to an expected column being missing. : key "y" value "y2" (closest match: "y") [renderer: GlyphRenderer(id='14758', ...)]
ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name. This could either be due to a misspelling or typo, or due to an expected column being missing. : key "y" value "y2" (closest match: "y") [renderer: GlyphRenderer(id='14758', ...)]
If it's helpful to know: I tried replacing 'y2' with 'y' and the script runs with no error, but then the upper right plot is blank.
This error seems like it would be an easy fix, but I was not able to resolve it.
Setting to 'y'
is the correct thing to do. The names passed to the glyph map to column names in the data source, and there is no "y2" column in your data source. The reason the plot is blank is because your x-coordinates are outside the explicit viewport range you are setting:
(base) ❯ python test.py
min x = 176.0, max x = 184.0
Wrote anscombe.html
By contrast the x-range of the plot you set is from x2dr.start = -0.12
to x2dr.end = 0.12
. So, all the data is very far off-screen. You can either adjust the plot bounds or adjust the x-coordinates. I don't know what is appropriate for your use case so I can't advise on that matter.
As a gentle helpful tip, it is almost always a good idea to take a quick look at the data when problems arise. Adding one print statement to show the x max/min immediately uncovered the issue.