5 Best Ways to Visualize Stacked Bar Charts in Python Using Bokeh Library

Rate this post

πŸ’‘ Problem Formulation: Stacked bar charts are a crucial tool for visualizing and comparing parts of a whole across different categories. In Python, achieving this with the Bokeh library involves understanding data structuring and leveraging Bokeh’s plotting capabilities. For example, a dataset containing monthly sales data for different products could be visualized using a stacked bar chart to show each product’s contribution to the total monthly sales.

Method 1: Using Bokeh’s vbar_stack() function

This method utilizes the vbar_stack() function provided by Bokeh to create stacked bars. The function stacks values vertically for each category and is best suited for comparing different groups within a discrete range. It requires data to be organized in a columnar data source and uses a list of column names that represent the ‘stackers’ – the different layers of the stacked bar.

Here’s an example:

from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource

data = {'months' : ['January', 'February', 'March'],
        'product_1' : [2, 1, 4],
        'product_2' : [5, 3, 3],
        'product_3' : [3, 2, 2]}

source = ColumnDataSource(data=data)

output_file("stacked_bar.html")

p = figure(x_range=data['months'], title="Product Sales by Month",
           toolbar_location=None, tools="")

p.vbar_stack(stackers=['product_1', 'product_2', 'product_3'], 
             x='months', source=source, width=0.9, 
             color=["blue", "red", "green"], legend_label=['Product 1', 'Product 2', 'Product 3'])

show(p)

The output of this code snippet is an interactive HTML file named “stacked_bar.html”, containing a stacked bar chart with bars for each month, depicting product sales. Each product’s sale is stacked on top of the other to give a visual sum for the month.

This code snippet initializes a Bokeh figure, then creates a stacked bar chart by calling the vbar_stack() function with the specified parameters. The data source is prepared using Bokeh’s ColumnDataSource, and different colors and legends are assigned to each ‘product’ for better differentiation and comprehension.

Method 2: Custom Stacked Bars with Rectangles

For a more hands-on approach, individual bars can be stacked manually using the rect() glyph function in Bokeh. This method provides more control over the appearance and behavior of each bar segment and is ideal for customized stacked charts where default functions may not suffice. Each rectangle represents a segment of the stack with specific coordinates, width, and height.

Here’s an example:

from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource

output_file("custom_stacked_bar.html")

data = {'months': ['January', 'February', 'March'],
        'products': [('Product 1', 'Product 2', 'Product 3')] * 3,
        'base': [0, 3, 1, 3, 6, 5],
        'top': [3, 5, 1, 6, 8, 7],
        'color': ["blue", "blue", "red", "red", "green", "green"]}

source = ColumnDataSource(data=data)

p = figure(y_range=data['months'], title="Custom Product Sales by Month",
           x_axis_label='Quantity', y_axis_label='Month')

p.rect(x="base", y="months", width=1, height=0.3, source=source,
       color="color", line_color=None)

show(p)

The output of this code snippet is an interactive HTML file named “custom_stacked_bar.html”, showcasing a custom stacked bar chart with rectangle glyphs for product sales across different months.

In this code snippet, custom rectangles are defined using the rect() glyph method for each product. This provides refined control over the starting point (base) and ending point (top) of each rectangle, thereby creating the stacking effect. The colors array ensures that each product segment is easily distinguishable.

Method 3: Hover Tool for Interactive Stacked Bars

Interactivity can be infused in Bokeh stacked bar charts with hover tools, which reveal more information about each segment when the mouse is hovered over them. This feature enhances the user experience by providing immediate access to detailed data without overcrowding the visual. The HoverTool is added to the plot and configured to display the relevant information.

Here’s an example:

from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource, HoverTool

output_file("interactive_stacked_bar.html")

source = ColumnDataSource(data=dict(months=['January', 'February', 'March'],
                                    product_1=[2, 1, 4],
                                    product_2=[5, 3, 3],
                                    product_3=[3, 2, 2]))

hover = HoverTool(tooltips=[
    ("Product 1", "@product_1"),
    ("Product 2", "@product_2"),
    ("Product 3", "@product_3")
])

p = figure(x_range=source.data['months'], title="Interactive Product Sales by Month",
           toolbar_location=None, tools=[hover])

p.vbar_stack(['product_1', 'product_2', 'product_3'], x='months', source=source,
             width=0.9, color=["blue", "red", "green"],
             legend_label=['Product 1', 'Product 2', 'Product 3'])

show(p)

The output of this code snippet is an interactive HTML file named “interactive_stacked_bar.html”, displaying a stacked bar chart with an interactive hover tool that shows sales information for each product on hover.

This implementation combines the stacking capability of vbar_stack() with a HoverTool that is configured with custom tooltips showing values of each product segment. This empowers users with more data on demand, enriching the data-driven storytelling capability of the chart.

Method 4: Stacked Bars with Callback for Drill-Down

A more advanced usage of Bokeh stacked bar charts includes adding JavaScript callbacks for interactive drill-down functionality. This method allows for executing custom JavaScript code in response to user actions, such as clicking on a chart segment to see detailed information or filter the data. It provides an interactive way to explore complex datasets.

Here’s an example:

from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource, CustomJS

output_file("callback_stacked_bar.html")

source = ColumnDataSource(data=dict(months=['January', 'February', 'March'],
                                    product_1=[2, 1, 4],
                                    product_2=[5, 3, 3],
                                    product_3=[3, 2, 2]))

callback = CustomJS(args=dict(source=source), code="""
    // Custom JavaScript code for interactivity
""")

p = figure(x_range=source.data['months'], title="Python Stacked Bar Chart with Callback",
           toolbar_location=None, tools="")

p.vbar_stack(['product_1', 'product_2', 'product_3'], x='months', width=0.9, 
             color=["blue", "red", "green"], source=source, 
             legend_label=['Product 1', 'Product 2', 'Product 3'])

p.js_on_click(callback)

show(p)

The output of this code snippet is an interactive HTML file named “callback_stacked_bar.html”. It showcases a stacked bar chart ready to execute a JavaScript callback when a segment is clicked, intended for a dynamic drill-down exploration.

Here, the plot is enhanced with a custom JavaScript CustomJS callback that can interact with the stacked bar chart elements on click events. While the custom JavaScript needs to be provided based on the user’s specific requirements for interactivity, this snippet illustrates the setup for potential interactive drill-downs.

Bonus One-Liner Method 5: Stacked Bars Utilizing pandas DataFrames

In cases where data is handled in pandas DataFrames, Bokeh simplifies the process with one-liner functions that directly accept DataFrame objects for plot creation. This one-liner approach is convenient and efficient for quick visualizations when working with standardized DataFrame structures.

Here’s an example:

import pandas as pd
from bokeh.plotting import figure, show, output_file
from bokeh.io import curdoc

output_file("one_liner_stacked_bar.html")

df = pd.DataFrame({'months': ['January', 'February', 'March'],
                   'product_1': [2, 1, 4],
                   'product_2': [5, 3, 3],
                   'product_3': [3, 2, 2]}).set_index('months')

p = figure(x_range=curdoc().session_context.request.arguments.get('months', 'January'), title="Product Sales by Month")
p.vbar_stack(stackers=['product_1', 'product_2', 'product_3'], x=df.index.values, width=0.9, color=["blue", "red", "green"], source=df)

show(p)

The output of this example is an interactive HTML file named “one_liner_stacked_bar.html” containing a stacked bar chart with product sales data from a pandas DataFrame.

The pandas DataFrame simplifies data management, and the creation of the bar chart is streamlined with the direct use of DataFrame columns as the data source in the Bokeh plot. Note that `curdoc` is used to set the initial x_range dynamically in some scenarios, which can be useful for web applications.

Summary/Discussion

  • Method 1: Using Bokeh’s vbar_stack() function. Straightforward method. Easy for beginners and suitable for conventional stacked bar charts. Limited customization options.
  • Method 2: Custom Stacked Bars with Rectangles. Offers high customization. Requires manual calculation of bar segments. Ideal for sophisticated visualizations with bespoke requirements.
  • Method 3: Hover Tool for Interactive Stacked Bars. Elevates the user experience by adding interactive elements. Information-density can be managed efficiently. Implementation requires additional configuration.
  • Method 4: Stacked Bars with Callback for Drill-Down. Highly interactive and suitable for detailed data explorations. Requires knowledge of JavaScript for interaction logic. Can be complex to implement.
  • Bonus Method 5: Stacked Bars Utilizing pandas DataFrames. Practical for efficient and rapid visualizations when the data is already in DataFrame format. It may not be suitable for all types of data arrangements.