Help on trying to render a Figure with multiple glyphs from a pandas DataFrame

Hi everyone,

I need some help on being able to render multiple glyphs on the same figure object using data coming from pandas DataFrame. For the purposes of the graphs I want to plot, I have already been able to do it for Series objects, but don’t know how to do it for DataFrames. I know its definitely possible, but I just need some suggestions here from you guys; even some pointers on where in the documnetation I should look will be helpful.

So I already have a function here that does plotting for the figure I want using a series object and it works fine:

from bokeh.plotting import figure , output_file, show, save
from bokeh.models import HoverTool, TapTool, OpenURL, ColumnDataSource
from collections import OrderedDict
def bokeh_plot(data, metric):
‘’’
The metric parameter must be a string that must be exactly the same as the name
of the column on the DataFrame or Series that contains all the data we want to plot
against the build numbers
‘’’

if isinstance(data, pd.Series):
# We generate two lists from the series object
buildnums = list(data.index)
datapts = list(data)
# We construct a dictionary from the two lists in order to pass the data into
# the ColumnDataSource instance because ColumnDataSource does not accept Series objects
source = ColumnDataSource(dict(x = buildnums, y=datapts))

p = figure(title="Geometric Mean of %s vs Build Number" %metric,
           tools="pan,wheel_zoom,reset,hover")

# Be sure to instantiate the circle glyph factory before the line glyph factory
# otherwise TapTool OpenURL on the circle won't work with the clickable link
p.circle(x = buildnums, y = datapts, radius=0.3, source = source,
fill_color="blue", fill_alpha=0.6, line_color=None)

p.line(x = buildnums, y = datapts)

hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
("(Build Number, Geometric Mean)", "(@x, @y)")
 ])

tap = TapTool(plot=p,
    action=OpenURL(url="http://192.168.1.253:8010/builders/Synthesis/builds/@x"))

p.tools.append(tap)

output_file("data_analysis_%s.html" % metric)
save(p)

``

But knowing that the ColumnDataSource is able to take in DataFrames directly, when I try adding this chunk:

if isinstance(data, pd.DataFrame):

dictionary = ColumnDataSource.from_df(data)
source = ColumnDataSource(dictionary)

# Obtain the list of buildnums and datapts via indexing the dictionary object
# these give us the x and y values for our plot
buildnums = dictionary['build_number']
datapts = dictionary['%s' %metric]

p = figure(title="Geometric Mean of %s vs Build Number" %metric,
           tools="pan,wheel_zoom,reset,hover")

p.circle(x = buildnums, y = datapts, radius=0.3, source =source,
fill_color="blue", fill_alpha=0.6, line_color=None)

p.line(x = buildnums, y = datapts)

hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
("(Build Number, Geometric Mean)", "(@x, @y)")
 ])

tap = TapTool(plot=p,
    action=OpenURL(url="http://192.168.1.253:8010/builders/Synthesis/builds/@x"))

p.tools.append(tap)

output_file("data_analysis_%s.html" % metric)
save(p)

``

When I try running my code with this chunk and passing in a DataFrame, the html file gets saved, but when I open it, I find that hovertool and tooltips are not working at all, totally unlike the one for Series object.

Please correct me if I’m using anything incorrectly here, and I would greatly appreciate any suggestions for alternative implementations to plot from a DataFrame. It will also be great if someone could explain to me, what is the purpose for us assigning the argument ‘source=source’ when we are calling the circle factory object , which I did in my code here.

thank you very much.

Oops sorry my errorneous remakr that “ColumnDataSource is able to take a pandas DataFrame object directly” - I meant to say its from_df method.

···

On Thursday, 7 May 2015 18:37:24 UTC+8, Augustine Koh wrote:

Hi everyone,

I need some help on being able to render multiple glyphs on the same figure object using data coming from pandas DataFrame. For the purposes of the graphs I want to plot, I have already been able to do it for Series objects, but don’t know how to do it for DataFrames. I know its definitely possible, but I just need some suggestions here from you guys; even some pointers on where in the documnetation I should look will be helpful.

So I already have a function here that does plotting for the figure I want using a series object and it works fine:

from bokeh.plotting import figure , output_file, show, save
from bokeh.models import HoverTool, TapTool, OpenURL, ColumnDataSource
from collections import OrderedDict
def bokeh_plot(data, metric):
‘’’
The metric parameter must be a string that must be exactly the same as the name
of the column on the DataFrame or Series that contains all the data we want to plot
against the build numbers
‘’’

if isinstance(data, pd.Series):
# We generate two lists from the series object
buildnums = list(data.index)
datapts = list(data)
# We construct a dictionary from the two lists in order to pass the data into
# the ColumnDataSource instance because ColumnDataSource does not accept Series objects
source = ColumnDataSource(dict(x = buildnums, y=datapts))

p = figure(title="Geometric Mean of %s vs Build Number" %metric,
           tools="pan,wheel_zoom,reset,hover")


# Be sure to instantiate the circle glyph factory before the line glyph factory
# otherwise TapTool OpenURL on the circle won't work with the clickable link
p.circle(x = buildnums, y = datapts, radius=0.3, source = source,
fill_color="blue", fill_alpha=0.6, line_color=None)

p.line(x = buildnums, y = datapts)

hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
("(Build Number, Geometric Mean)", "(@x, @y)")
 ])

tap = TapTool(plot=p,
    action=OpenURL(url="[http://192.168.1.253:8010/builders/Synthesis/builds/@x](http://192.168.1.253:8010/builders/Synthesis/builds/@x)"))

p.tools.append(tap)

output_file("data_analysis_%s.html" % metric)
save(p)

``

But knowing that the ColumnDataSource is able to take in DataFrames directly, when I try adding this chunk:

if isinstance(data, pd.DataFrame):

dictionary = ColumnDataSource.from_df(data)
source = ColumnDataSource(dictionary)

# Obtain the list of buildnums and datapts via indexing the dictionary object
# these give us the x and y values for our plot
buildnums = dictionary['build_number']
datapts = dictionary['%s' %metric]

p = figure(title="Geometric Mean of %s vs Build Number" %metric,
           tools="pan,wheel_zoom,reset,hover")

p.circle(x = buildnums, y = datapts, radius=0.3, source =source,
fill_color="blue", fill_alpha=0.6, line_color=None)

p.line(x = buildnums, y = datapts)

hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
("(Build Number, Geometric Mean)", "(@x, @y)")
 ])

tap = TapTool(plot=p,
    action=OpenURL(url="[http://192.168.1.253:8010/builders/Synthesis/builds/@x](http://192.168.1.253:8010/builders/Synthesis/builds/@x)"))

p.tools.append(tap)

output_file("data_analysis_%s.html" % metric)
save(p)

``

When I try running my code with this chunk and passing in a DataFrame, the html file gets saved, but when I open it, I find that hovertool and tooltips are not working at all, totally unlike the one for Series object.

Please correct me if I’m using anything incorrectly here, and I would greatly appreciate any suggestions for alternative implementations to plot from a DataFrame. It will also be great if someone could explain to me, what is the purpose for us assigning the argument ‘source=source’ when we are calling the circle factory object , which I did in my code here.

thank you very much.

If you could post example code that was easier to test - maybe a slimmed down version with some sample data, it may be easier to help.

···

On Thu, May 7, 2015 at 3:38 AM, ‘Augustine Koh’ via Bokeh Discussion - Public [email protected] wrote:

Oops sorry my errorneous remakr that “ColumnDataSource is able to take a pandas DataFrame object directly” - I meant to say its from_df method.

On Thursday, 7 May 2015 18:37:24 UTC+8, Augustine Koh wrote:

Hi everyone,

I need some help on being able to render multiple glyphs on the same figure object using data coming from pandas DataFrame. For the purposes of the graphs I want to plot, I have already been able to do it for Series objects, but don’t know how to do it for DataFrames. I know its definitely possible, but I just need some suggestions here from you guys; even some pointers on where in the documnetation I should look will be helpful.

So I already have a function here that does plotting for the figure I want using a series object and it works fine:

from bokeh.plotting import figure , output_file, show, save
from bokeh.models import HoverTool, TapTool, OpenURL, ColumnDataSource
from collections import OrderedDict
def bokeh_plot(data, metric):
‘’’
The metric parameter must be a string that must be exactly the same as the name
of the column on the DataFrame or Series that contains all the data we want to plot
against the build numbers
‘’’

if isinstance(data, pd.Series):
# We generate two lists from the series object
buildnums = list(data.index)
datapts = list(data)
# We construct a dictionary from the two lists in order to pass the data into
# the ColumnDataSource instance because ColumnDataSource does not accept Series objects
source = ColumnDataSource(dict(x = buildnums, y=datapts))

p = figure(title="Geometric Mean of %s vs Build Number" %metric,
           tools="pan,wheel_zoom,reset,hover")


# Be sure to instantiate the circle glyph factory before the line glyph factory
# otherwise TapTool OpenURL on the circle won't work with the clickable link
p.circle(x = buildnums, y = datapts, radius=0.3, source = source,
fill_color="blue", fill_alpha=0.6, line_color=None)

p.line(x = buildnums, y = datapts)

hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
("(Build Number, Geometric Mean)", "(@x, @y)")
 ])

tap = TapTool(plot=p,
    action=OpenURL(url="[http://192.168.1.253:8010/builders/Synthesis/builds/@x](http://192.168.1.253:8010/builders/Synthesis/builds/@x)"))

p.tools.append(tap)

output_file("data_analysis_%s.html" % metric)
save(p)

``

But knowing that the ColumnDataSource is able to take in DataFrames directly, when I try adding this chunk:

if isinstance(data, pd.DataFrame):

dictionary = ColumnDataSource.from_df(data)
source = ColumnDataSource(dictionary)

# Obtain the list of buildnums and datapts via indexing the dictionary object
# these give us the x and y values for our plot
buildnums = dictionary['build_number']
datapts = dictionary['%s' %metric]

p = figure(title="Geometric Mean of %s vs Build Number" %metric,
           tools="pan,wheel_zoom,reset,hover")

p.circle(x = buildnums, y = datapts, radius=0.3, source =source,
fill_color="blue", fill_alpha=0.6, line_color=None)

p.line(x = buildnums, y = datapts)

hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
("(Build Number, Geometric Mean)", "(@x, @y)")
 ])

tap = TapTool(plot=p,
    action=OpenURL(url="[http://192.168.1.253:8010/builders/Synthesis/builds/@x](http://192.168.1.253:8010/builders/Synthesis/builds/@x)"))

p.tools.append(tap)

output_file("data_analysis_%s.html" % metric)
save(p)

``

When I try running my code with this chunk and passing in a DataFrame, the html file gets saved, but when I open it, I find that hovertool and tooltips are not working at all, totally unlike the one for Series object.

Please correct me if I’m using anything incorrectly here, and I would greatly appreciate any suggestions for alternative implementations to plot from a DataFrame. It will also be great if someone could explain to me, what is the purpose for us assigning the argument ‘source=source’ when we are calling the circle factory object , which I did in my code here.

thank you very much.

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].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/70afec58-eb4e-4916-9642-9fb03509cdac%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.