Add regression line to bokeh

What are you trying to do? Hi, Im traying to add a linnear regression to the bokeh crossfit example: bokeh/examples/app/crossfilter at branch-3.0 · bokeh/bokeh (github.com)

I know how to do a linear regression in python, but dont know how to connect it to the figure. the figure is not plotted by show, its plotted wiht curdoc, and dont know how to add the lane. I`ve asked this in stockoverflow, but they give me the tipical result (that doesnt fit to me … because curdoc is not used) : PYTHON: how can I add a linear regression to this bokeh? - Stack Overflow

The code is in above links

Hi @jsgaston,

You can do one of two things,

  1. Insert the data directly into a figure using Line
  2. Insert the data from a ColumnDataSource object

You can see on First steps, they outline this for you. From the above link modified a bit,

import numpy as np
from scipy.stats import linregress

from bokeh.plotting import figure, show
#from bokeh.plotting import figure, curdoc

# prepare some data
x = np.array([1, 2, 3, 4, 5])
y = np.array([6, 7, 2, 4, 5])

# Do your regression
res = linregress(x, y)

# create a new plot with a title and axis labels
p = figure(title="Simple line example", x_axis_label="x", y_axis_label="y")

# add scatter data with legend
p.circle(x, y, radius=0.05, legend_label="Data")

# add your regression fit
y_regress = res.slope * x + res.intercept
p.line(x=x, y=y_regress, color='red', legend_label="Regression", name="regression")

# show the results
show(p)
#curdoc().add_root(p)

In your case just change the legend_label, x and y data accordingly to your regression data. You can use the name parameter (from Line or any Glyph) if you need to search through glyphs in the figure, as needed for more complicated logic.

If you are trying to serve using bokeh serve myapp.py you can replace show with curdoc, and show(p) with curdoc().add_root(p).

1 Like

hi … I have a prob with this code … dont know where to exactly paste it(make it work) in my code:

‘’’ A crossfilter plot map that uses the Auto MPG dataset_. This example
demonstrates the relationship of datasets together. A hover tooltip displays
information on each dot.

.. note::
    This example needs the Pandas package to run.

.. _Auto MPG dataset: https://archive.ics.uci.edu/ml/datasets/auto+mpg

'''
import pandas as pd

from bokeh.layouts import column, row
from bokeh.models import Select
from bokeh.palettes import Spectral5
from bokeh.plotting import curdoc, figure
from bokeh.sampledata.autompg import autompg_clean as df

df = df.copy()

SIZES = list(range(6, 22, 3))
COLORS = Spectral5
N_SIZES = len(SIZES)
N_COLORS = len(COLORS)

# data cleanup
df.cyl = df.cyl.astype(str)
df.yr = df.yr.astype(str)
del df['name']

columns = sorted(df.columns)
discrete = [x for x in columns if df[x].dtype == object]
continuous = [x for x in columns if x not in discrete]

def create_figure():
    xs = df[x.value].values
    ys = df[y.value].values
    x_title = x.value.title()
    y_title = y.value.title()

    kw = dict()
    if x.value in discrete:
        kw['x_range'] = sorted(set(xs))
    if y.value in discrete:
        kw['y_range'] = sorted(set(ys))
    kw['title'] = "%s vs %s" % (x_title, y_title)

    p = figure(height=600, width=800, tools='pan,box_zoom,hover,reset', **kw)
    p.xaxis.axis_label = x_title
    p.yaxis.axis_label = y_title

    if x.value in discrete:
        p.xaxis.major_label_orientation = pd.np.pi / 4

    sz = 9
    if size.value != 'None':
        if len(set(df[size.value])) > N_SIZES:
            groups = pd.qcut(df[size.value].values, N_SIZES, duplicates='drop')
        else:
            groups = pd.Categorical(df[size.value])
        sz = [SIZES[xx] for xx in groups.codes]

    c = "#31AADE"
    if color.value != 'None':
        if len(set(df[color.value])) > N_COLORS:
            groups = pd.qcut(df[color.value].values, N_COLORS, duplicates='drop')
        else:
            groups = pd.Categorical(df[color.value])
        c = [COLORS[xx] for xx in groups.codes]

    p.circle(x=xs, y=ys, color=c, size=sz, line_color="white", alpha=0.6, hover_color='white', hover_alpha=0.5)

    return p


def update(attr, old, new):
    layout.children[1] = create_figure()


x = Select(title='X-Axis', value='mpg', options=columns)
x.on_change('value', update)

y = Select(title='Y-Axis', value='hp', options=columns)
y.on_change('value', update)

size = Select(title='Size', value='None', options=['None'] + continuous)
size.on_change('value', update)

color = Select(title='Color', value='None', options=['None'] + continuous)
color.on_change('value', update)

controls = column(x, y, color, size, width=200)
layout = row(controls, create_figure())

curdoc().add_root(layout)
curdoc().title = "Crossfilter"