Using CustomJS to make a dynamic scatter plot with Bokeh- Issue with “nonexistent column name”
I thought I found a concrete example that I could leverage here, but the same logic is not working for me, unfortunately.
I have two questions:
Is what I'm attempting to do even possible: send a dynamic scatter plot in a html document that allows you to control what is plotted on the x & y axes. I've succeeded with static plots, but haven't cracked dynamic plots yet.
Where is my code going wrong (see below?)
Here are the relevant pieces of code (in order. I have a dataframe that I've converted into "source" using ColumnDataSource.
I create an initial plot (note, at this point, there are no columns called 'x' and 'y'. I create those in the callback function later) :
plot.circle('x', 'y',
source=source,
color={'field': 'Picker',
'transform': mapper},
legend='Picker')
I create two dropdown menus (note that the options in each correspond to the columns from "source" I'd want people to be able to choose from)
x_menu=Select(options=['Box Office', 'Difference', 'Price Paid'],
value='Box Office',
title='What do you want to put on the x axis')
y_menu=Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
I create the callback:
callback = CustomJS (args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
data['y']=data[cb_obj.value]
source.change.emit();
""")
I assign the callbacks to the dropdown menus:
x_menu.callback = callback
y_menu.callback = callback
And then I try to show the plot:
show(row(widgetbox(x_menu, y_menu), plot))
But it returns the below error:
ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name: x, y [renderer: GlyphRenderer(id='df96b108-e2e4-4b8c-b0c6-12df40b4205d', ...)]
Any help is very much appreciated. Thank you!
python bokeh
add a comment |
I thought I found a concrete example that I could leverage here, but the same logic is not working for me, unfortunately.
I have two questions:
Is what I'm attempting to do even possible: send a dynamic scatter plot in a html document that allows you to control what is plotted on the x & y axes. I've succeeded with static plots, but haven't cracked dynamic plots yet.
Where is my code going wrong (see below?)
Here are the relevant pieces of code (in order. I have a dataframe that I've converted into "source" using ColumnDataSource.
I create an initial plot (note, at this point, there are no columns called 'x' and 'y'. I create those in the callback function later) :
plot.circle('x', 'y',
source=source,
color={'field': 'Picker',
'transform': mapper},
legend='Picker')
I create two dropdown menus (note that the options in each correspond to the columns from "source" I'd want people to be able to choose from)
x_menu=Select(options=['Box Office', 'Difference', 'Price Paid'],
value='Box Office',
title='What do you want to put on the x axis')
y_menu=Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
I create the callback:
callback = CustomJS (args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
data['y']=data[cb_obj.value]
source.change.emit();
""")
I assign the callbacks to the dropdown menus:
x_menu.callback = callback
y_menu.callback = callback
And then I try to show the plot:
show(row(widgetbox(x_menu, y_menu), plot))
But it returns the below error:
ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name: x, y [renderer: GlyphRenderer(id='df96b108-e2e4-4b8c-b0c6-12df40b4205d', ...)]
Any help is very much appreciated. Thank you!
python bokeh
add a comment |
I thought I found a concrete example that I could leverage here, but the same logic is not working for me, unfortunately.
I have two questions:
Is what I'm attempting to do even possible: send a dynamic scatter plot in a html document that allows you to control what is plotted on the x & y axes. I've succeeded with static plots, but haven't cracked dynamic plots yet.
Where is my code going wrong (see below?)
Here are the relevant pieces of code (in order. I have a dataframe that I've converted into "source" using ColumnDataSource.
I create an initial plot (note, at this point, there are no columns called 'x' and 'y'. I create those in the callback function later) :
plot.circle('x', 'y',
source=source,
color={'field': 'Picker',
'transform': mapper},
legend='Picker')
I create two dropdown menus (note that the options in each correspond to the columns from "source" I'd want people to be able to choose from)
x_menu=Select(options=['Box Office', 'Difference', 'Price Paid'],
value='Box Office',
title='What do you want to put on the x axis')
y_menu=Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
I create the callback:
callback = CustomJS (args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
data['y']=data[cb_obj.value]
source.change.emit();
""")
I assign the callbacks to the dropdown menus:
x_menu.callback = callback
y_menu.callback = callback
And then I try to show the plot:
show(row(widgetbox(x_menu, y_menu), plot))
But it returns the below error:
ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name: x, y [renderer: GlyphRenderer(id='df96b108-e2e4-4b8c-b0c6-12df40b4205d', ...)]
Any help is very much appreciated. Thank you!
python bokeh
I thought I found a concrete example that I could leverage here, but the same logic is not working for me, unfortunately.
I have two questions:
Is what I'm attempting to do even possible: send a dynamic scatter plot in a html document that allows you to control what is plotted on the x & y axes. I've succeeded with static plots, but haven't cracked dynamic plots yet.
Where is my code going wrong (see below?)
Here are the relevant pieces of code (in order. I have a dataframe that I've converted into "source" using ColumnDataSource.
I create an initial plot (note, at this point, there are no columns called 'x' and 'y'. I create those in the callback function later) :
plot.circle('x', 'y',
source=source,
color={'field': 'Picker',
'transform': mapper},
legend='Picker')
I create two dropdown menus (note that the options in each correspond to the columns from "source" I'd want people to be able to choose from)
x_menu=Select(options=['Box Office', 'Difference', 'Price Paid'],
value='Box Office',
title='What do you want to put on the x axis')
y_menu=Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
I create the callback:
callback = CustomJS (args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
data['y']=data[cb_obj.value]
source.change.emit();
""")
I assign the callbacks to the dropdown menus:
x_menu.callback = callback
y_menu.callback = callback
And then I try to show the plot:
show(row(widgetbox(x_menu, y_menu), plot))
But it returns the below error:
ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name: x, y [renderer: GlyphRenderer(id='df96b108-e2e4-4b8c-b0c6-12df40b4205d', ...)]
Any help is very much appreciated. Thank you!
python bokeh
python bokeh
asked Nov 13 '18 at 18:51
E LarsonE Larson
84
84
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It would be easier to help if you gave a self-contained minimal example (code that we can just copy, paste and run). With that said, here is something that might help you to get started. You were already very close to this solution, but I guess the important part is to have one callback for each menu.
I hope this helps :-)
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Select
from bokeh.plotting import figure, show, ColumnDataSource
# Define some random data
dataframe = pd.DataFrame({
'Difference': np.sin(np.linspace(0, 100, 500)),
'Price': np.cos(np.linspace(0, 100, 500)),
'Metacritic': np.sin(np.linspace(0, 100, 500)),
'Rotten Tomatoes': np.cos(np.linspace(0, 200, 500)),
})
# Set x and y-axis defaults
dataframe['x'] = dataframe['Difference']
dataframe['y'] = dataframe['Metacritic']
# Create Bokeh's ColumnDataSource
source = ColumnDataSource(data=dataframe)
# Create the plot figure
plot = figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source)
# Create the dropdown menus
x_menu = Select(options=['Difference', 'Price'],
value='Difference',
title='What do you want to put on the x axis')
y_menu = Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
# Create two callbacks, one for each menu
callback_x = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
source.change.emit();
""")
callback_y = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['y']=data[cb_obj.value]
source.change.emit();
""")
# Assign callbacks to menu widgets
x_menu.callback = callback_x
y_menu.callback = callback_y
# Show the html document with a layout
show(row(widgetbox(x_menu, y_menu), plot))
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287715%2fusing-customjs-to-make-a-dynamic-scatter-plot-with-bokeh-issue-with-nonexisten%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It would be easier to help if you gave a self-contained minimal example (code that we can just copy, paste and run). With that said, here is something that might help you to get started. You were already very close to this solution, but I guess the important part is to have one callback for each menu.
I hope this helps :-)
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Select
from bokeh.plotting import figure, show, ColumnDataSource
# Define some random data
dataframe = pd.DataFrame({
'Difference': np.sin(np.linspace(0, 100, 500)),
'Price': np.cos(np.linspace(0, 100, 500)),
'Metacritic': np.sin(np.linspace(0, 100, 500)),
'Rotten Tomatoes': np.cos(np.linspace(0, 200, 500)),
})
# Set x and y-axis defaults
dataframe['x'] = dataframe['Difference']
dataframe['y'] = dataframe['Metacritic']
# Create Bokeh's ColumnDataSource
source = ColumnDataSource(data=dataframe)
# Create the plot figure
plot = figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source)
# Create the dropdown menus
x_menu = Select(options=['Difference', 'Price'],
value='Difference',
title='What do you want to put on the x axis')
y_menu = Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
# Create two callbacks, one for each menu
callback_x = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
source.change.emit();
""")
callback_y = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['y']=data[cb_obj.value]
source.change.emit();
""")
# Assign callbacks to menu widgets
x_menu.callback = callback_x
y_menu.callback = callback_y
# Show the html document with a layout
show(row(widgetbox(x_menu, y_menu), plot))
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
add a comment |
It would be easier to help if you gave a self-contained minimal example (code that we can just copy, paste and run). With that said, here is something that might help you to get started. You were already very close to this solution, but I guess the important part is to have one callback for each menu.
I hope this helps :-)
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Select
from bokeh.plotting import figure, show, ColumnDataSource
# Define some random data
dataframe = pd.DataFrame({
'Difference': np.sin(np.linspace(0, 100, 500)),
'Price': np.cos(np.linspace(0, 100, 500)),
'Metacritic': np.sin(np.linspace(0, 100, 500)),
'Rotten Tomatoes': np.cos(np.linspace(0, 200, 500)),
})
# Set x and y-axis defaults
dataframe['x'] = dataframe['Difference']
dataframe['y'] = dataframe['Metacritic']
# Create Bokeh's ColumnDataSource
source = ColumnDataSource(data=dataframe)
# Create the plot figure
plot = figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source)
# Create the dropdown menus
x_menu = Select(options=['Difference', 'Price'],
value='Difference',
title='What do you want to put on the x axis')
y_menu = Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
# Create two callbacks, one for each menu
callback_x = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
source.change.emit();
""")
callback_y = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['y']=data[cb_obj.value]
source.change.emit();
""")
# Assign callbacks to menu widgets
x_menu.callback = callback_x
y_menu.callback = callback_y
# Show the html document with a layout
show(row(widgetbox(x_menu, y_menu), plot))
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
add a comment |
It would be easier to help if you gave a self-contained minimal example (code that we can just copy, paste and run). With that said, here is something that might help you to get started. You were already very close to this solution, but I guess the important part is to have one callback for each menu.
I hope this helps :-)
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Select
from bokeh.plotting import figure, show, ColumnDataSource
# Define some random data
dataframe = pd.DataFrame({
'Difference': np.sin(np.linspace(0, 100, 500)),
'Price': np.cos(np.linspace(0, 100, 500)),
'Metacritic': np.sin(np.linspace(0, 100, 500)),
'Rotten Tomatoes': np.cos(np.linspace(0, 200, 500)),
})
# Set x and y-axis defaults
dataframe['x'] = dataframe['Difference']
dataframe['y'] = dataframe['Metacritic']
# Create Bokeh's ColumnDataSource
source = ColumnDataSource(data=dataframe)
# Create the plot figure
plot = figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source)
# Create the dropdown menus
x_menu = Select(options=['Difference', 'Price'],
value='Difference',
title='What do you want to put on the x axis')
y_menu = Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
# Create two callbacks, one for each menu
callback_x = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
source.change.emit();
""")
callback_y = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['y']=data[cb_obj.value]
source.change.emit();
""")
# Assign callbacks to menu widgets
x_menu.callback = callback_x
y_menu.callback = callback_y
# Show the html document with a layout
show(row(widgetbox(x_menu, y_menu), plot))
It would be easier to help if you gave a self-contained minimal example (code that we can just copy, paste and run). With that said, here is something that might help you to get started. You were already very close to this solution, but I guess the important part is to have one callback for each menu.
I hope this helps :-)
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Select
from bokeh.plotting import figure, show, ColumnDataSource
# Define some random data
dataframe = pd.DataFrame({
'Difference': np.sin(np.linspace(0, 100, 500)),
'Price': np.cos(np.linspace(0, 100, 500)),
'Metacritic': np.sin(np.linspace(0, 100, 500)),
'Rotten Tomatoes': np.cos(np.linspace(0, 200, 500)),
})
# Set x and y-axis defaults
dataframe['x'] = dataframe['Difference']
dataframe['y'] = dataframe['Metacritic']
# Create Bokeh's ColumnDataSource
source = ColumnDataSource(data=dataframe)
# Create the plot figure
plot = figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source)
# Create the dropdown menus
x_menu = Select(options=['Difference', 'Price'],
value='Difference',
title='What do you want to put on the x axis')
y_menu = Select(options=['Metacritic', 'Rotten Tomatoes'],
value='Metacritic',
title='What do you want to put on the y axis')
# Create two callbacks, one for each menu
callback_x = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['x']=data[cb_obj.value]
source.change.emit();
""")
callback_y = CustomJS(args=dict(source=source), code="""
console.log('changed selected option', cb_obj.value)
var data=source.data
data['y']=data[cb_obj.value]
source.change.emit();
""")
# Assign callbacks to menu widgets
x_menu.callback = callback_x
y_menu.callback = callback_y
# Show the html document with a layout
show(row(widgetbox(x_menu, y_menu), plot))
answered Nov 13 '18 at 21:02
Azrael_DDAzrael_DD
465
465
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
add a comment |
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Thanks so much. Good call on adding the random data so that people can just run it. Unfortunately, I'm still having similar issues. I'll send a new snippet of code below to clarify the issue
– E Larson
Nov 13 '18 at 22:12
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
Never mind... I glazed right over your "set x and y defaults." That was the issue with the nonexistent columns (on top of adding the two callbacks).
– E Larson
Nov 13 '18 at 22:23
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287715%2fusing-customjs-to-make-a-dynamic-scatter-plot-with-bokeh-issue-with-nonexisten%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown