Updating animated figure with multiple Glyphs (e.g. boxplot)

Hello there,

First, thanks for this amazing work. I love it!

I am trying to create an animated plot, as described in this github example. As I understand it, the flow is:

With bokeh-server running

  1. Create figure object
  2. Populate the figure with Glyphs
  3. Create data_source object attached to the figure
  4. Update the data attribute of the data_source object with new data
  5. Update the current session by invoking cursession().store_objects(…)
  6. Repeat from 3 when needed

Now, I would like to be able to update a boxplot figure, which I create as in the gallery example. In that example, each box is created by creating the stems, then creating the upper and lower halves of the rectangles, and finally creating the whiskers, as in:

# stems
p.segment(cats, upper.score, cats, q3.score, line_width=2, line_color="black")
p.segment(cats, lower.score, cats, q1.score, line_width=2, line_color="black")

# boxes
p.rect(cats, (q3.score+q2.score)/2, 0.7, q3.score-q2.score,
    fill_color="#E08E79", line_width=2, line_color="black")
p.rect(cats, (q2.score+q1.score)/2, 0.7, q2.score-q1.score,
    fill_color="#3B8686", line_width=2, line_color="black")

# whiskers (almost-0 height rects simpler than segments)
p.rect(cats, lower.score, 0.2, 0.01, line_color="black")
p.rect(cats, upper.score, 0.2, 0.01, line_color="black") 

My question is how to update the data attribute of the data_source object for the case when multiple Glyphs (in my case segments and rectangles) have been drawn on the same figure. In the github example to which I linked above, I have a single Glyph in the figure (an annular ring) and can refer to the inner radius and outer radius:

ds.data[“inner_radius”] = rmin

ds.data[“outer_radius”] = rmax

How can I do the same for a figure which is populated by multiple Glyphs?

Thanks a lot!

Nikos

Here is a short update on my problem (and a very partial solution), hopefully it will catch someone’s attention and fetch some answers.

As a short update: I want to have various kinds of plots which are being updated in real time with streaming data. Currently, I have scatterplots and line plots working. What I would like to also include are box and whisker plots, and histograms.

Here is my progress so far:

I found out two ways two update a plot which is embedded in an ipython notebook with new data:

For scatter plots and line plots

output_server("animated")  


    p = figure(x_axis_type = "datetime")
    p.line(datesdata, data, color="navy", legend="Start Time Dispersion")
    p.circle(datesdata, data, color="navy")

    renderer = p.select(dict(type=GlyphRenderer))
    ds = renderer[0].data_source

    show(p)

Then push new data with

ds.data["x"] = datesdata
    ds.data["y"] = data
    cursession().store_objects(ds)

This way, only the line plot is updated

Alternate way:

output_server("animated")

    ds = ColumnDataSource(data=dict(x=datesdata, y=data))

    f = figure(x_axis_type = "datetime", tools='pan,wheel_zoom,box_zoom,reset,resize,box_select')
    f.line("x", "y", color='navy', legend='Start Time Dispersion', source=d_source)
    f.circle("x", "y", color='navy', source=d_source)

    show(f)

Then push new data the same way as above
ds.data["x"] = datesdata
     ds.data["y"] = data
     cursession().store_objects(ds)

Now both line and circles are updated.

However, I am unable to generalize this method on plots which are populated with other elements (e.g. rect). When I try:

    d_source = ColumnDataSource(data=dict(x=datesdata, y=(data[1, :] + data[2, :])/2))

    f = figure(x_axis_type = "datetime", tools='pan,wheel_zoom,box_zoom,reset,resize,box_select')

    f.rect("x", "y", 0.7, 0.1, fill_color="#E08E79", line_width=2, line_color="black")
    show(f)

I get the error:

Column name 'x' does not appear in data source <bokeh.models.sources.ColumnDataSource object at 0x107323c90>

If you want to see more details and try a working example of this, head over to https://github.com/nikos-daniilidis/bokeh-starter/tree/master/live-notebook.

Feel free to clone the repo to play around with it.

If you decide to clone the repository:

Open DataGenerator.ipynb and run it. It will start producing json reports in the /reports directory.

After a few jsons have been p[roduced, open DataConsumer.ipynb and run the kind of streaming plot you are interested in producing.

Does anyone have any feedback on how to get box and whisker plot to update? Ideally, I would want to be able to update a plot which has been generated similarly to the following:

def boxplot_series(x_labels, p5, p25, p50, p75, p95, TOOLS = "pan,wheel_zoom,box_zoom,reset,save"):
p = figure(tools=TOOLS, background_fill="#EFE8E2", title="", x_range=x_labels)

    # stems
    p.segment(x_labels, p5, x_labels, p25, line_width=2, line_color="black")
    p.segment(x_labels, p75, x_labels, p95, line_width=2, line_color="black")

    # boxes
    p.rect(x_labels, (p25 + p50) / 2, 0.7, p50-p25,
           fill_color="#E08E79", line_width=2, line_color="black")
    p.rect(x_labels, (p50 + p75) / 2, 0.7, p75-p50,
           fill_color="#3B8686", line_width=2, line_color="black")

    # whiskers (almost-0 height rects simpler than segments)
    p.rect(x_labels, p5, 0.2, 0.01, line_color="black")
    p.rect(x_labels, p95, 0.2, 0.01, line_color="black")

    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = "white"
    p.grid.grid_line_width = 2
    p.xaxis.major_label_text_font_size="12pt"

    show(p)
    return p

Thanks,

Nikos

···

On Sun, Jun 7, 2015 at 8:43 PM, nikosd [email protected] wrote:

Hello there,

First, thanks for this amazing work. I love it!

I am trying to create an animated plot, as described in this github example. As I understand it, the flow is:

With bokeh-server running

  1. Create figure object
  2. Populate the figure with Glyphs
  3. Create data_source object attached to the figure
  4. Update the data attribute of the data_source object with new data
  5. Update the current session by invoking cursession().store_objects(…)
  6. Repeat from 3 when needed

Now, I would like to be able to update a boxplot figure, which I create as in the gallery example. In that example, each box is created by creating the stems, then creating the upper and lower halves of the rectangles, and finally creating the whiskers, as in:

# stems
p.segment(cats, upper.score, cats, q3.score, line_width=2, line_color="black")
p.segment(cats, lower.score, cats, q1.score, line_width=2, line_color="black")

# boxes
p.rect(cats, (q3.score+q2.score)/2, 0.7, q3.score-q2.score,
    fill_color="#E08E79", line_width=2, line_color="black")
p.rect(cats, (q2.score+q1.score)/2, 0.7, q2.score-q1.score,
    fill_color="#3B8686", line_width=2, line_color="black")

# whiskers (almost-0 height rects simpler than segments)
p.rect(cats, lower.score, 0.2, 0.01, line_color="black")
p.rect(cats, upper.score, 0.2, 0.01, line_color="black") 

My question is how to update the data attribute of the data_source object for the case when multiple Glyphs (in my case segments and rectangles) have been drawn on the same figure. In the github example to which I linked above, I have a single Glyph in the figure (an annular ring) and can refer to the inner radius and outer radius:

ds.data[“inner_radius”] = rmin

ds.data[“outer_radius”] = rmax

How can I do the same for a figure which is populated by multiple Glyphs?

Thanks a lot!

Nikos

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/d90e97de-7726-4b92-8970-d7eaefc3c3b4%40continuum.io.

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