Updating columndatasource overwrites original source

I have a simple plot showing two patches with a slider that changes the color of these patches. The code to update the color functions much like the gapminder example. However, the update seems to overwrite the first data source. The two patches should be (red, red) at slider value=0, (red, blue) at value=1, and (yellow, blue) at value=2. Going from 0 to 1 to 2 changes the colors correctly, but when dragging the slider back to value=0, the patches remain as (red,blue) instead of going back to (red,red). The change of going backward from value=2 to value=1 works correctly. I tried printing out the data, and it seems that the columndatasource at source[0] seems to get overwritten by the data at source[1]. The problem only seems to occur for source[0] and nowhere else.

I don’t understand why this happens. Any help would be appreciated!

Here’s the code that seems to produce this problem:

from bokeh.plotting import figure, show

from bokeh.models import HoverTool, ColumnDataSource, Slider, Button

import pandas as pd

import collections

from bokeh.io import curdoc

from bokeh.layouts import layout

x = [[0,1,1,0],[2,3,3,2]]

y = [[0,0,1,1],[0,0,1,1]]

p = figure(plot_width = 500, plot_height=500)

sources = {}

sources2 = {}

color = [‘red’,‘red’]

data = [0,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[0] = ColumnDataSource(df)

sources2[0] = ColumnDataSource(df)

color = [‘red’,‘blue’]

data=[2,3]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[1] = ColumnDataSource(df)

sources2[1] = ColumnDataSource(df)

color = [‘yellow’,‘blue’]

data=[4,5]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[2] = ColumnDataSource(df)

sources2[2] = ColumnDataSource(df)

temp = p.patches(‘x’, ‘y’, source=sources[0], color=‘color’)

hover = HoverTool(renderers=[temp], tooltips=[(‘data’,’@data’)])

def slider_update(attrname, old, new):

val = slider.value

temp.data_source.data = sources[val].data

slider = Slider(start=0, end=2, value=0, step=1, title=“index”)

slider.on_change(‘value’, slider_update)

layout = layout([

[p],

[slider],

], sizing_mode=‘fixed’)

curdoc().add_root(layout)

curdoc().title = “replacing cds”

Hi,

The typical usage is not to create a completely new ColumnDataSource, but to update the .data attribute of an existing data source. for example:

  https://github.com/bokeh/bokeh/blob/master/examples/app/sliders.py#L66

Thanks,

Bryan

···

On Nov 14, 2016, at 11:02 AM, [email protected] wrote:

I have a simple plot showing two patches with a slider that changes the color of these patches. The code to update the color functions much like the gapminder example. However, the update seems to overwrite the first data source. The two patches should be (red, red) at slider value=0, (red, blue) at value=1, and (yellow, blue) at value=2. Going from 0 to 1 to 2 changes the colors correctly, but when dragging the slider back to value=0, the patches remain as (red,blue) instead of going back to (red,red). The change of going backward from value=2 to value=1 works correctly. I tried printing out the data, and it seems that the columndatasource at source[0] seems to get overwritten by the data at source[1]. The problem only seems to occur for source[0] and nowhere else.

I don't understand why this happens. Any help would be appreciated!

Here's the code that seems to produce this problem:

from bokeh.plotting import figure, show
from bokeh.models import HoverTool, ColumnDataSource, Slider, Button
import pandas as pd
import collections
from bokeh.io import curdoc
from bokeh.layouts import layout

x = [[0,1,1,0],[2,3,3,2]]
y = [[0,0,1,1],[0,0,1,1]]

p = figure(plot_width = 500, plot_height=500)

sources = {}
sources2 = {}

color = ['red','red']
data = [0,1]
df = pd.DataFrame({'x': x, 'y': y,'data':data, 'color':color})
sources[0] = ColumnDataSource(df)
sources2[0] = ColumnDataSource(df)

color = ['red','blue']
data=[2,3]
df = pd.DataFrame({'x': x, 'y': y,'data':data, 'color':color})
sources[1] = ColumnDataSource(df)
sources2[1] = ColumnDataSource(df)

color = ['yellow','blue']
data=[4,5]
df = pd.DataFrame({'x': x, 'y': y,'data':data, 'color':color})
sources[2] = ColumnDataSource(df)
sources2[2] = ColumnDataSource(df)

temp = p.patches('x', 'y', source=sources[0], color='color')
hover = HoverTool(renderers=[temp], tooltips=[('data','@data')])

def slider_update(attrname, old, new):
    val = slider.value
    temp.data_source.data = sources[val].data

slider = Slider(start=0, end=2, value=0, step=1, title="index")
slider.on_change('value', slider_update)

layout = layout([
    [p],
    [slider],
], sizing_mode='fixed')

curdoc().add_root(layout)
curdoc().title = "replacing cds"

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected]nuum.io.
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/77b2c7ce-f05d-48e7-beb7-1894cf6d7363%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Stephanie,

I think Bryan is right. This seems to fix the problem (I’ve added some comments where appropriate):

from bokeh.plotting import figure, show

from bokeh.models import HoverTool, ColumnDataSource, Slider, Button

import pandas as pd

import collections

from bokeh.io import curdoc

from bokeh.layouts import layout

x = [[0,1,1,0],[2,3,3,2]]

y = [[0,0,1,1],[0,0,1,1]]

p = figure(plot_width = 500, plot_height=500)

sources = # Switched to a list instead of dictionary

color = [‘red’,‘red’]

data = [0,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources.append(df.to_dict(orient=‘list’)) # Append dataframe to list

color = [‘red’,‘blue’]

data=[2,3]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources.append(df.to_dict(orient=‘list’)) # Append dataframe to list

color = [‘yellow’,‘blue’]

data=[4,5]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources.append(df.to_dict(orient=‘list’)) # Append dataframe to list

temp = p.patches(‘x’, ‘y’, source=ColumnDataSource(sources[0]), color=‘color’) #Note the CDS wrapped around the dict

hover = HoverTool(renderers=[temp], tooltips=[(‘data’,’@data’)])

def slider_update(attrname, old, new):

val = slider.value

temp.data_source.data = sources[val]  # Removed '.data' and supplied dict

slider = Slider(start=0, end=2, value=0, step=1, title=“index”)

slider.on_change(‘value’, slider_update)

layout = layout([

[p],

[slider],

], sizing_mode=‘fixed’)

curdoc().add_root(layout)

curdoc().title = “replacing cds”

···

On Monday, November 14, 2016 at 11:03:00 AM UTC-5, [email protected] wrote:

I have a simple plot showing two patches with a slider that changes the color of these patches. The code to update the color functions much like the gapminder example. However, the update seems to overwrite the first data source. The two patches should be (red, red) at slider value=0, (red, blue) at value=1, and (yellow, blue) at value=2. Going from 0 to 1 to 2 changes the colors correctly, but when dragging the slider back to value=0, the patches remain as (red,blue) instead of going back to (red,red). The change of going backward from value=2 to value=1 works correctly. I tried printing out the data, and it seems that the columndatasource at source[0] seems to get overwritten by the data at source[1]. The problem only seems to occur for source[0] and nowhere else.

I don’t understand why this happens. Any help would be appreciated!

Here’s the code that seems to produce this problem:

from bokeh.plotting import figure, show

from bokeh.models import HoverTool, ColumnDataSource, Slider, Button

import pandas as pd

import collections

from bokeh.io import curdoc

from bokeh.layouts import layout

x = [[0,1,1,0],[2,3,3,2]]

y = [[0,0,1,1],[0,0,1,1]]

p = figure(plot_width = 500, plot_height=500)

sources = {}

sources2 = {}

color = [‘red’,‘red’]

data = [0,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[0] = ColumnDataSource(df)

sources2[0] = ColumnDataSource(df)

color = [‘red’,‘blue’]

data=[2,3]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[1] = ColumnDataSource(df)

sources2[1] = ColumnDataSource(df)

color = [‘yellow’,‘blue’]

data=[4,5]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[2] = ColumnDataSource(df)

sources2[2] = ColumnDataSource(df)

temp = p.patches(‘x’, ‘y’, source=sources[0], color=‘color’)

hover = HoverTool(renderers=[temp], tooltips=[(‘data’,’@data’)])

def slider_update(attrname, old, new):

val = slider.value
temp.data_source.data = sources[val].data

slider = Slider(start=0, end=2, value=0, step=1, title=“index”)

slider.on_change(‘value’, slider_update)

layout = layout([

[p],
[slider],

], sizing_mode=‘fixed’)

curdoc().add_root(layout)

curdoc().title = “replacing cds”

Thanks! This seems to work for this example, but when I add ‘nan’ to the data, it fails again. If all of the nans are float(‘nan’), then the example works for the first value=0, then fails for other values. If all of the nans are the string ‘NaN’, then the first value=0 (the initial load) fails, but then everything works after. Here’s an example with the string 'NaN’s. Is there any good workaround or solution to make the first value=0 (first frame) load correctly as well?

from bokeh.plotting import figure, show

from bokeh.models import HoverTool, ColumnDataSource, Slider, Button

import pandas as pd

from bokeh.io import curdoc

from bokeh.layouts import layout

x = [[0,1,1,0, ‘NaN’, 0,1,1,0],[2,3,3,2, ‘NaN’, 2,3,3,2]]

y = [[0,0,1,1, ‘NaN’, 2,2,3,3],[0,0,1,1, ‘NaN’, 2,2,3,3]]

p = figure(plot_width = 500, plot_height=500)

sources = [None,None,None]

color = [‘red’,‘red’]

data = [0,‘NaN’]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[0] = df.to_dict(orient=‘list’)

color = [‘red’,‘blue’]

data=[2,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[1] = df.to_dict(orient=‘list’)

color = [‘yellow’,‘blue’]

data=[4,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[2] = df.to_dict(orient=‘list’)

temp = p.patches(‘x’, ‘y’, source=ColumnDataSource(sources[0]), color=‘color’)

hover = HoverTool(renderers=[temp], tooltips=[(‘data’,’@data’)])

def slider_update(attrname, old, new):

val = slider.value

temp.data_source.data = sources[val]

slider = Slider(start=0, end=2, value=0, step=1, title=“index”)

slider.on_change(‘value’, slider_update)

layout = layout([

[p],

[slider],

], sizing_mode=‘fixed’)

curdoc().add_root(layout)

curdoc().title = “replacing cds”

···

On Wednesday, November 16, 2016 at 8:41:48 PM UTC-5, [email protected] wrote:

Stephanie,

I think Bryan is right. This seems to fix the problem (I’ve added some comments where appropriate):

from bokeh.plotting import figure, show

from bokeh.models import HoverTool, ColumnDataSource, Slider, Button

import pandas as pd

import collections

from bokeh.io import curdoc

from bokeh.layouts import layout

x = [[0,1,1,0],[2,3,3,2]]

y = [[0,0,1,1],[0,0,1,1]]

p = figure(plot_width = 500, plot_height=500)

sources = # Switched to a list instead of dictionary

color = [‘red’,‘red’]

data = [0,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources.append(df.to_dict(orient=‘list’)) # Append dataframe to list

color = [‘red’,‘blue’]

data=[2,3]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources.append(df.to_dict(orient=‘list’)) # Append dataframe to list

color = [‘yellow’,‘blue’]

data=[4,5]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources.append(df.to_dict(orient=‘list’)) # Append dataframe to list

temp = p.patches(‘x’, ‘y’, source=ColumnDataSource(sources[0]), color=‘color’) #Note the CDS wrapped around the dict

hover = HoverTool(renderers=[temp], tooltips=[(‘data’,’@data’)])

def slider_update(attrname, old, new):

val = slider.value
temp.data_source.data = sources[val]  # Removed '.data' and supplied dict

slider = Slider(start=0, end=2, value=0, step=1, title=“index”)

slider.on_change(‘value’, slider_update)

layout = layout([

[p],
[slider],

], sizing_mode=‘fixed’)

curdoc().add_root(layout)

curdoc().title = “replacing cds”

On Monday, November 14, 2016 at 11:03:00 AM UTC-5, [email protected] wrote:

I have a simple plot showing two patches with a slider that changes the color of these patches. The code to update the color functions much like the gapminder example. However, the update seems to overwrite the first data source. The two patches should be (red, red) at slider value=0, (red, blue) at value=1, and (yellow, blue) at value=2. Going from 0 to 1 to 2 changes the colors correctly, but when dragging the slider back to value=0, the patches remain as (red,blue) instead of going back to (red,red). The change of going backward from value=2 to value=1 works correctly. I tried printing out the data, and it seems that the columndatasource at source[0] seems to get overwritten by the data at source[1]. The problem only seems to occur for source[0] and nowhere else.

I don’t understand why this happens. Any help would be appreciated!

Here’s the code that seems to produce this problem:

from bokeh.plotting import figure, show

from bokeh.models import HoverTool, ColumnDataSource, Slider, Button

import pandas as pd

import collections

from bokeh.io import curdoc

from bokeh.layouts import layout

x = [[0,1,1,0],[2,3,3,2]]

y = [[0,0,1,1],[0,0,1,1]]

p = figure(plot_width = 500, plot_height=500)

sources = {}

sources2 = {}

color = [‘red’,‘red’]

data = [0,1]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[0] = ColumnDataSource(df)

sources2[0] = ColumnDataSource(df)

color = [‘red’,‘blue’]

data=[2,3]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[1] = ColumnDataSource(df)

sources2[1] = ColumnDataSource(df)

color = [‘yellow’,‘blue’]

data=[4,5]

df = pd.DataFrame({‘x’: x, ‘y’: y,‘data’:data, ‘color’:color})

sources[2] = ColumnDataSource(df)

sources2[2] = ColumnDataSource(df)

temp = p.patches(‘x’, ‘y’, source=sources[0], color=‘color’)

hover = HoverTool(renderers=[temp], tooltips=[(‘data’,’@data’)])

def slider_update(attrname, old, new):

val = slider.value
temp.data_source.data = sources[val].data

slider = Slider(start=0, end=2, value=0, step=1, title=“index”)

slider.on_change(‘value’, slider_update)

layout = layout([

[p],
[slider],

], sizing_mode=‘fixed’)

curdoc().add_root(layout)

curdoc().title = “replacing cds”