In [ ]:
from bokeh.charts import output_notebook, show
from bokeh.charts.glyphs import BarGlyph

output_notebook()

Composite Glyph

One or more actual glyphs that have been grouped together to represent some set of data, which respond to some standardized set of graphics operations.

In a chart, a composite glyph is generated for each group of data. For example, a box glyph will produce one box for a box plot. This is composed of multiple glyphs, but represents a single group of data.

This guide walks through the creation and use of composite glyphs.

BarGlyph

A simple bar has two components. It has some location along an axis, then it has some height from that axis. A bar can be created from a single value, or it can be created through aggregation. For example:

Bar from single value


In [ ]:
bar = BarGlyph(label='a', values=[1])
bar.data

Bar from multiple values

Notice the difference in height.


In [ ]:
bar = BarGlyph(label='a', values=[1, 2, 3, 4])
bar.data

Simplified input using same order


In [ ]:
bar = BarGlyph('a', 1)
bar.data

Operations on Composite Glyphs

Grammar of Graphics describes some common graphical operations that each glyph type would respond differently to. A common operation for bars would be stacking

Un-Stacked


In [ ]:
bar1 = BarGlyph('foo', 1)
bar2 = BarGlyph('foo', 2)

print('No stacking')
print('bar1 y: %s, bar2 y: %s' % (bar1.data['y'], bar2.data['y']) )

Stacked


In [ ]:
from bokeh.charts.operations import stack

bar1, bar2 = stack(bar1, bar2)

print('With Stacking')
print('bar1 y: %s, bar2 y: %s' % (bar1.data['y'], bar2.data['y']) )

Producing Combined Data Source


In [ ]:
from bokeh.charts.utils import comp_glyphs_to_df

# utility that uses pandas.concat to concatenate each CompositeGlyph.df
comp_glyphs_to_df(bar1, bar2)

Standalone Use of Composite Glyphs

Setup


In [ ]:
from bokeh.charts.chart import Chart
from bokeh.models.ranges import DataRange1d, FactorRange
from bokeh.io import curdoc, curstate

def add_chart_to_doc(chart):
    "Handle adding chart to doc."
    curdoc()._current_plot = chart
    curdoc().add_root(chart)

Build Bars and Add Them Manually to Chart

In the chart below, the bars corresponding to foo overlap.


In [ ]:
# two bars overlap on the same label/index
bar1 = BarGlyph(label='foo', values=[1])
bar2 = BarGlyph('foo', 2)

# only the third bar doesn't overlap
bar3 = BarGlyph('bar', 3)

# composite glyphs can have multiple renderers, so we get them all
renderers = []
for bar in [bar1, bar2, bar3]:
    renderers += bar.renderers

# create a chart and directly add the renderers
c = Chart(renderers=renderers)

# add ranges/scales (typically handled by builder)
c.add_ranges('x', FactorRange(factors=['foo', 'bar']))
c.add_ranges('y', DataRange1d(start=0, end=4))

c.add_scales('x', 'auto')
c.add_scales('y', 'auto')

# build the chart (typically called by create_and_build)
c.start_plot()

# add chart to doc (typically handled by create_and_build)
add_chart_to_doc(c)

show(c)

Stack the Bars, then Show Chart

One potential way to handle overlapping bars is to stack them. See below that stacking the bars results in a stacked bar chart.


In [ ]:
stack(bar1, bar2, bar3)

show(c)

In [ ]: