0
votes

I would like to use a loop as a generator to create individual glyphs to generate a scatter plot. My x values are categorical values. I'm starting from the following simple example.

from bokeh.plotting import figure, show

xvals = ['one', 'two', 'three']
p = figure(x_range=xvals)

i=1
for value in xvals:
   p.circle(x=value,y=i)
   i+=1

show(p)

This results in Bokeh throwing the error:

Bokeh Error attempted to retrieve property array for nonexistent field 'one'

I'm guessing this can be sorted by using columndatasource and passing it as the source to the glyph rendering function. I've tried various ways to structure the data and pass it to the renderer, but without luck. The columndatasource object wants to be passed a dictionary with the format:

data = {'x_values': [1, 2, 3, 4, 5],
    'y_values': [6, 7, 2, 3, 6]}

I am not able to call a complete list of y values before the generator as they will be computed during the loop in my real function. Is there any way around this? This is super easy to do with pyplot, but I need to use Bokeh for its interactive plots.

Thanks!

1
I'm guessing from the crickets that this is not possible. Can bokeh handle scatter plots with multiple y values for each x value? With categorical data?JeremyD
For anyone who is trying to accomplish similar, I was not able to get this approach to work. I instead wrote a generator function to create a pandas dataframe which I then fed back to the glyph renderer using the ColumnDataSource object. I will post a minimal example below.JeremyD

1 Answers

0
votes

The ColumnDataSource object must be used. Here is a way to implement a generator for y values with categorical x values using a pandas dataframe.

import pandas
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
from random import randrange

xvals = ['one', 'two', 'three', 'four']
yvals = []

#Here is the generator function
for num in xvals:
    yvals.append(randrange(0,10))

#Construct a dataframe from generator function        
df=pandas.DataFrame({'XVals': xvals, 'YVals': yvals})
source = ColumnDataSource(df)

#Create the plot
p = figure(x_range=xvals)
p.circle(x='XVals',y='YVals', source=source)
show(p)