Share @ LinkedIn Facebook  bqplot, data-visualization
bqplot - Interactive Plots using Internal Object Model API

bqplot - Interactive Charts using Internal Object Model API [Python]

The bqplot is an interactive plotting library of Python. It's developed by the Bloomberg development team. The bqplot is developed on top of ipywidgets widgets library hence all component of bqplot chart is a widget. The bqplot provides two different API for creating charts.

  • Matplotlib Pyplot like API
  • Internal Object Model API

We have already covered a tutorial on creating charts using matplotlib pyplot like API. As a part of this tutorial, we'll be covering an internal object model API which is very flexible. It lets us create individual chart components (like axis, scales, glyph, figure, etc.) and then merge them all to create full chart. We'll be using datasets available from scikit-learn for plotting various charts.

If you are interested in learning bqplot's matplotlib pyplot like API then please feel free to refer to our tutorial on the same:

We also suggest that you learn about ipywidgets as it'll help you with this tutorial. If you are interested in learning about ipywidgets then please feel free to go through our tutorials on the same.

We'll start by importing necessary libraries.

In [1]:
import pandas as pd
import numpy as np

import bqplot

Load Datasets

We'll be using IRIS flowers, wine dataset, and Apple OHLC datasets for charting purposes.

  • IRIS Flowers dataset: It has measurement information about three different types of IRIS flowers (IRIS-setosa, IRIS-virginica, IRIS-versicolor). It's available from scikit-learn.
  • Wine Dataset - It has information about various ingredients measurements used in creating three different types of wines. It's available from scikit-learn.
  • Apple OHLC Dataset: It OHLC data for Apple from Apr-2019 - Mar-2020.

We'll be converting each dataset into a pandas dataframe in order to better maintain it and make it more usable for charting purposes.

In [2]:
from sklearn.datasets import load_iris, load_wine

iris = load_iris()
iris_df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
iris_df["FlowerType"] = [iris.target_names[target] for target in iris.target]

iris_df.head()
Out[2]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) FlowerType
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
In [3]:
wine = load_wine()
wine_df = pd.DataFrame(data=wine.data, columns=wine.feature_names)
wine_df["WineType"] = [wine.target_names[target] for target in wine.target]

wine_df.head()
Out[3]:
alcohol malic_acid ash alcalinity_of_ash magnesium total_phenols flavanoids nonflavanoid_phenols proanthocyanins color_intensity hue od280/od315_of_diluted_wines proline WineType
0 14.23 1.71 2.43 15.6 127.0 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065.0 class_0
1 13.20 1.78 2.14 11.2 100.0 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050.0 class_0
2 13.16 2.36 2.67 18.6 101.0 2.80 3.24 0.30 2.81 5.68 1.03 3.17 1185.0 class_0
3 14.37 1.95 2.50 16.8 113.0 3.85 3.49 0.24 2.18 7.80 0.86 3.45 1480.0 class_0
4 13.24 2.59 2.87 21.0 118.0 2.80 2.69 0.39 1.82 4.32 1.04 2.93 735.0 class_0
In [4]:
apple_df = pd.read_csv("datasets/AAPL.csv")
apple_df["Date"] = pd.to_datetime(apple_df["Date"])

apple_df.head()
Out[4]:
Date Open High Low Close Adj Close Volume
0 2019-04-05 196.449997 197.100006 195.929993 197.000000 194.454758 18526600
1 2019-04-08 196.419998 200.229996 196.339996 200.100006 197.514709 25881700
2 2019-04-09 200.320007 202.850006 199.229996 199.500000 196.922470 35768200
3 2019-04-10 198.679993 200.740005 198.179993 200.619995 198.027985 21695300
4 2019-04-11 200.850006 201.000000 198.440002 198.949997 196.379578 20900800

Commonly Followed Steps to Create bqplot Chart

Below is a list of steps that will be commonly followed to create an interactive chart using bqplot.

  1. Load Data
  2. Create bqplot scale objects like OrdinalScale for sequential data, LinearScale for quantitative data, etc for X and Y-axis.
  3. Create Charts like bar charts, line charts passing data, and scales to it along with other chart attributes like color, edge size, line sizes, etc.
  4. Create X and Y-axis using the Axis object of bqplot passing scales created in step 2 to it.
  5. Create final figure using the Figure object of bqplot using the chart (step-3) and axes (step-4) along with other attributes of a figure like a title, legend location, etc.

Line Charts

The first chart that we'll create is a line chart of Apple stock close prices. We'll follow the above-mentioned steps to create chart. We'll first create DateScale for x-axis dates and LinearScale for float closing prices on the y-axis. We'll then create the Lines chart by giving data for XY-axis, scales and other chart attributes like color, labels, legend, etc. We'll then create axis for both axis passing scale and axis attributes like label, orientation, grids information, etc. We'll then create a final figure using lines chart and axes objects created along with setting a few figure attributes like figure title, legend location, etc.

In [ ]:
from bqplot import DateScale, LinearScale, Lines, Axis, Figure

x_date = DateScale()
y_linear = LinearScale()

line = Lines(x=apple_df.Date, y=apple_df.Close,
             scales={'x':x_date, 'y': y_linear},
             labels=["Close Price ($)"],
             colors=["dodgerblue"],
             display_legend=True,)

ax_x = Axis(scale=x_date, label="Date", grid_lines="solid", )
ax_y = Axis(scale=y_linear, label="Price($)", orientation="vertical", grid_lines="solid")

fig = Figure(marks=[line],
       axes=[ax_x, ax_y],
       legend_location = "top-left",
       title="Apple Stock Close Price ($) [Apr,2019 - Mar-2020]",)

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Saving Figure

We can easily save the bqplot chart as png, or SVG format. We need to call the save_png or save_svg method on the figure object passing it filename by which to save the chart.

In [6]:
fig.save_png("apple_close_price.png")
In [7]:
fig.save_svg("apple_close_price.svg")

Below we are again creating a line chart using the same steps as the previous chart but this time we have added two lines to the chart. We have added lines for open and close prices both. The values that we pass to the labels attribute of Lines will be used to create a legend. We also have changed marker style and marker size for the line chart.

We can add a margin to the figure by passing a dictionary of the top, bottom, left, and right margin to the fig_margin attribute of the Figure method.

In [ ]:
x_date = DateScale()
y_linear = LinearScale()

line1 = Lines(x=apple_df.Date, y=[apple_df.Open, apple_df.Close],
              scales={'x':x_date, 'y': y_linear},
              labels=["Open Price ($)", "Close Price ($)"], colors=["dodgerblue", "tomato"], display_legend=True,
              marker="circle", marker_size=15)

ax_x = Axis(scale=x_date, label="Date", grid_lines="solid", )
ax_y = Axis(scale=y_linear, label="Price($)", orientation="vertical", grid_lines="solid")

Figure(marks=[line1],
       axes=[ax_x, ax_y],
       legend_location = "top-left",
       title="Apple Stock Open-Close Price ($) [Apr,2019 - Mar-2020]",
       fig_margin= dict(top=50, bottom=30, left=50, right=20))

bqplot - Interactive Charts using Internal Object Model API [Python]

Area Charts

Below we are creating an area chart that covers the area covered by the closing price of Apple stock. We can create an area chart by using the same code as that of the line chart from the previous step with the addition of only one parameter to the Lines() method. We need to pass the fill parameter with the value bottom. It'll fill the area below the line.

In [ ]:
from bqplot import DateScale, LinearScale, Lines, Axis, Figure

x_date = DateScale()
y_linear = LinearScale()

area = Lines(x=apple_df.Date, y=apple_df.Close,
             scales={'x':x_date, 'y': y_linear},
             colors=["tomato"],
             labels=["Close Price ($)"],  display_legend=True,
             fill="bottom",)


ax_x = Axis(scale=x_date, label="Date", grid_lines="solid", )
ax_y = Axis(scale=y_linear, label="Price($)", orientation="vertical", grid_lines="solid")

Figure(marks=[area],
       axes=[ax_x, ax_y],
       legend_location = "top-left",
       title="Apple Stock Close Price ($) Area Chart [Apr,2019 - Mar-2020]",)

bqplot - Interactive Charts using Internal Object Model API [Python]

Below we have created anther area chart with the area under open and close prices getting highlighted. We have used the same steps as previous to create an area chart. We have changed opacities for both area charts using the fill_opacities attribute. We have passed two floats for two area charts. All other code is the same as that of the previous step.

In [ ]:
x_date = DateScale()
y_linear = LinearScale()

area = Lines(x=apple_df.Date, y=[apple_df.Open, apple_df.Close],
             scales={'x':x_date, 'y': y_linear},
             colors=["lime", "tomato"],
             labels=["Open Price ($)", "Close Price ($)"],  display_legend=True,
             fill_opacities=[0.5, 0.5],
             opacities=[0.5, 0.5],
             fill="bottom",)

ax_x = Axis(scale=x_date, label="Date", grid_lines="solid", )
ax_y = Axis(scale=y_linear, label="Price($)", orientation="vertical", grid_lines="solid")

Figure(marks=[area],
       axes=[ax_x, ax_y],
       legend_location = "top-left",
       title="Apple Stock Open-Close Price ($) Area Chart [Apr,2019 - Mar-2020]",)

bqplot - Interactive Charts using Internal Object Model API [Python]

Scatter Plot

The third chart that we have created using the bqplot object model API is scatter plot of sepal length and sepal width of IRIS flower data. We have created both X and Y scales as LinearScale for this chart. We have also modified the attribute of charts like default_opacities and default_size to change opacities and size of the circle marker.

We also have set offset for the X and Y axis as well have introduced tick formating.

In [ ]:
from bqplot import Scatter

x_linear = LinearScale()
y_linear = LinearScale()

scat1 = Scatter(x=iris_df[iris.feature_names[0]], y=iris_df[iris.feature_names[1]],
                scales={'x':x_linear, 'y': y_linear}, colors=['green'],
                default_opacities=[0.7],
                default_size=35)

ax_x = Axis(scale=x_linear, label=iris.feature_names[0],
            label_offset="35px",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label=iris.feature_names[1],
            orientation="vertical", label_offset="35px",
            tick_format="0.1f")

Figure(marks=[scat1],
       axes=[ax_x, ax_y],
       title="%s vs %s Scatter Chart"%(iris.feature_names[0].upper(), iris.feature_names[1].upper()),
       fig_margin= dict(top=50, bottom=40, left=50, right=20),
      )

bqplot - Interactive Charts using Internal Object Model API [Python]

Adding Tooltip

We can add a tooltip to the chart by creating an object of class Tooltip and setting it as tooltip attribute of the chart as explained below. We need to pass the tooltip list of fields from the chart whose values will be displayed in the tooltip along with labels for that fields to the Tooltip constructor.

In [12]:
from bqplot import Tooltip

scat1.tooltip = Tooltip(fields=['x', 'y'], labels=[iris.feature_names[0], iris.feature_names[1]])

Below we have created another scatter chart the same as the previous step but this time we have modified even more attributes of axis, chart, and figure. We have modified grid colors, tick style, grid line format, tick format, axes label colors, tick colors, etc.

In [ ]:
from bqplot import Scatter

x_linear = LinearScale()
y_linear = LinearScale()

scat2 = Scatter(x=iris_df[iris.feature_names[0]], y=iris_df[iris.feature_names[1]],
                scales={'x':x_linear, 'y': y_linear}, colors=['green'],
                default_opacities=[0.7],
                default_size=35)

ax_x = Axis(scale=x_linear, label=iris.feature_names[0],
            label_offset="35px",
            grid_lines="solid", grid_color="cyan", color="red", label_color="red",
            tick_format="0.1f", tick_style={"font-size":"15px", "font-weight":"bold"} )
ax_y = Axis(scale=y_linear, label=iris.feature_names[1], label_color="red",
            orientation="vertical", label_offset="35px",
            grid_lines="solid", grid_color="cyan", color="red",
            tick_format="0.1f", tick_style={"font-size":"15px", "font-weight":"bold"} )

scat2.tooltip = Tooltip(fields=['x', 'y'], labels=[iris.feature_names[0], iris.feature_names[1]])

Figure(marks=[scat2],
       axes=[ax_x, ax_y],
       title="%s vs %s Scatter Chart"%(iris.feature_names[0].upper(), iris.feature_names[1].upper()),
       fig_margin= dict(top=50, bottom=40, left=50, right=20),
       title_style={"font-weight":"bold"}
      )

bqplot - Interactive Charts using Internal Object Model API [Python]

Below is another example of a scatter chart which is the same as the last chart but with more modification of various chart attributes. We have modified marker style as well as have added labels for each marker.

In [ ]:
x_linear = LinearScale()
y_linear = LinearScale()

color_mapper = {"setosa":"red", "virginica":"green", "versicolor":"blue"}

scat3 = Scatter(x=iris_df[iris.feature_names[0]], y=iris_df[iris.feature_names[1]],
               marker="cross",
               scales={'x':x_linear, 'y': y_linear}, colors=[color_mapper[val] for val in iris_df.FlowerType],
               default_opacities=[0.6], names=iris_df.FlowerType,
               default_size=35)

ax_x = Axis(scale=x_linear, label=iris.feature_names[0],
            label_offset="35px",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label=iris.feature_names[1],
            orientation="vertical", label_offset="35px",
            tick_format="0.1f")

fig = Figure(marks=[scat3],
           axes=[ax_x, ax_y],
           title="%s vs %s Scatter Chart"%(iris.feature_names[0].upper(), iris.feature_names[1].upper()),
           fig_margin= dict(top=50, bottom=40, left=50, right=20),
      )

fig.layout.height="600px"

scat3.tooltip = Tooltip(fields=['x', 'y', "names"], labels=[iris.feature_names[0], iris.feature_names[1], "FlowerType"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

In [ ]:
x_linear = LinearScale()
y_linear = LinearScale()

color_mapper = {"setosa":"red", "virginica":"green", "versicolor":"blue"}

scat4 = Scatter(x=iris_df[iris.feature_names[0]], y=iris_df[iris.feature_names[1]],
               marker="cross",
               scales={'x':x_linear, 'y': y_linear}, colors=[color_mapper[val] for val in iris_df.FlowerType],
               default_opacities=[0.6], names=iris_df.FlowerType,
               default_size=35)

ax_x = Axis(scale=x_linear, label=iris.feature_names[0],
            label_offset="35px",
            grid_lines="dashed", grid_color="cyan", color="dodgerblue",label_color="dodgerblue",
            tick_format="0.1f", tick_style={"font-size":"15px", "font-weight":"bold"} )
ax_y = Axis(scale=y_linear, label=iris.feature_names[1],
            orientation="vertical", label_offset="35px",
            grid_lines="dashed", grid_color="cyan", color="dodgerblue",label_color="dodgerblue",
            tick_format="0.1f", tick_style={"font-size":"15px", "font-weight":"bold"} )

fig = Figure(marks=[scat4],
           axes=[ax_x, ax_y],
           title="%s vs %s Scatter Chart"%(iris.feature_names[0].upper(), iris.feature_names[1].upper()),
           fig_margin= dict(top=50, bottom=40, left=50, right=20),
           title_style={"font-weight":"bold"}
      )

fig.layout.height="600px"

scat4.tooltip = Tooltip(fields=['x', 'y', "names"], labels=[iris.feature_names[0], iris.feature_names[1], "FlowerType"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Bar Chart

The fourth chart type that we'll introduce is the bar chart. We'll be plotting below bar chart avg malic acid used per each category of wine.

We have first created a dataframe that has information about the average quantity of each ingredient per wine category. We'll be reusing this dataframe in the future as well.

We have created X-axis as OrdinalScale and Y-axis as LinearScale. The reason behind using OrdinalScale for X-axis is due to only three different categories of wine.

We have then created a bar chart using the Bars() constructor. We have also modified various chart attributes like labels, line width, bar width, line color, label color, label size, y-axis value limits, etc.

We have then created axes for both the X and Y axis using scales for them along with various axis attributes. We also have a modified the figure size this time by setting width and height of the layout of the figure. As bqplot is internally based on ipywidgets, it provides a layout attribute like ipywidgets widgets.

In [ ]:
from bqplot import OrdinalScale, Bars

avg_wine_df = wine_df.groupby(by="WineType").mean().reset_index()

x_ord = OrdinalScale()
y_linear = LinearScale()

bar1 = Bars(x=avg_wine_df.index, y=avg_wine_df.malic_acid,
           scales={'x':x_ord, 'y': y_linear},
           colors=["dodgerblue"], opacities=[0.8],
           stroke_width=1.5, stroke="red", padding=0.2,
           label_display=True, label_display_vertical_offset=-15,label_font_style={"font-weight":"bold", "font-size":"15px", "font-color": "white"},
           restrict_y=(0, 4)
           )

ax_x = Axis(scale=x_ord, label="WineType",
            label_offset="35px",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label="Malic Acid",
            orientation="vertical", label_offset="35px",
            tick_format="0.1f")

fig = Figure(marks=[bar1],
             axes=[ax_x, ax_y],
             title="Avg %s Bar Chart"%("malic acid".upper()),
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"lightgray"}
      )

bar1.tooltip = Tooltip(fields=['x', 'y'], labels=["WineType", "Avg Malic Acid"], formats=["0.1f", "0.2f"])

fig.layout.width="700px"
fig.layout.height="500px"

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Below we have created the same bar chart as the previous step but this time bars are laid out horizontally. We have also modified a few chart attributes like bar colors, label colors, grid colors, background colors, etc.

In [ ]:
from bqplot import OrdinalScale, Bars

avg_wine_df = wine_df.groupby(by="WineType").mean().reset_index()

x_ord = OrdinalScale()
y_linear = LinearScale()

bar2 = Bars(x=avg_wine_df.index, y=avg_wine_df.malic_acid,
           scales={'x':x_ord, 'y': y_linear},
           orientation="horizontal",
           colors=["dodgerblue", "tomato", "lime"], opacities=[0.8],
           stroke_width=1.5, stroke="black", padding=0.2,
           label_display=True, label_display_vertical_offset=-5,label_font_style={"font-weight":"bold", "font-size":"15px", "fill":"white"},
           restrict_y=(0, 4)
           )

ax_x = Axis(scale=x_ord, label="WineType",
            label_offset="35px", orientation="vertical",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label= "Avg Malic Acid",
            label_offset="35px",
            tick_format="0.1f")

fig = Figure(marks=[bar2],
             axes=[ax_x, ax_y],
             title="Avg %s Bar Chart"%("malic acid".upper()),
             fig_margin= dict(top=60, bottom=40, left=60, right=70),
             background_style = {"fill":"gray"}
      )

fig.layout.width="600px"

bar2.tooltip = Tooltip(fields=['x', 'y'], labels=["WineType", "Avg Malic Acid"], formats=["0.1f", "0.2f"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Below we have created another example demonstrating bar chart creation using bqplot object model API. This time we have created side by side bar chart explaining the average alcohol, average malic acid, and average ash per each wine category. We have even modified various chart attributes to improve the look and feel of the chart.

In [ ]:
x_ord = OrdinalScale()
y_linear = LinearScale()

bar3 = Bars(x=avg_wine_df.index, y=[avg_wine_df.alcohol, avg_wine_df.malic_acid, avg_wine_df.ash],
           scales={'x':x_ord, 'y': y_linear}, type="grouped",
           labels=["Alcohol", "Malic Acid", "ash"], display_legend=True,
           colors=["dodgerblue", "lime", "orange"], opacities=[0.8],
           stroke_width=1.5, stroke="black", padding=0.2,
           label_display=True, label_display_vertical_offset=-18,label_font_style={"font-weight":"bold", "font-size":"15px", "fill":"white"},
           restrict_y=(0, 4)
           )

ax_x = Axis(scale=x_ord, label="WineType",
            label_offset="35px",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label="Alcohol, Malic Acid",
            orientation="vertical", label_offset="35px",
            tick_format="0.1f")

fig = Figure(marks=[bar3],
             axes=[ax_x, ax_y],
             legend_location="top",
             title="Avg Alcohol, Malic Acid Gropued Bar Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"gray"},
             legend_style={"fill":"black"},
             legend_text={"font-size":"17px"}
      )

fig.layout.width="800px"
fig.layout.height="600px"

bar3.tooltip = Tooltip(fields=['x', 'y'], labels=["WineType", "Avg Quantity"], formats=["0.1f", "0.2f"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Below we have created an example demonstrating the creation of a stacked bar chart using bqplot internal object model API. We have created a stacked bar chart depicting average alcohol, average malic acid, average ash, average color, average phenols, and average flavanoids distribution per wine category. We can convert a normal bar chart to a stacked bar chart by setting the type parameter of Bars() constructor to stacked value.

In [ ]:
x_ord = OrdinalScale()
y_linear = LinearScale()

y_vals = [avg_wine_df.alcohol, avg_wine_df.malic_acid, avg_wine_df.ash, avg_wine_df.color_intensity, avg_wine_df.total_phenols, avg_wine_df.flavanoids]
bar4 = Bars(x=avg_wine_df.index, y=y_vals,
           scales={'x':x_ord, 'y': y_linear}, type="stacked",
           labels=["Alcohol","Malic Acid","Ash", "Color Intensity", "Total Phenols", "Flavanoids"], display_legend=True,
           colors=["dodgerblue", "lime", "tomato", "orange", "fuchsia", "gray"], opacities=[0.8],
           stroke_width=1.5, stroke="black", padding=0.4,
           restrict_y=(0, 4)
           )

ax_x = Axis(scale=x_ord, label="WineType",
            label_offset="35px",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label="Ingredients",
            orientation="vertical", label_offset="35px",
            tick_format="0.1f")

fig = Figure(marks=[bar4],
             axes=[ax_x, ax_y],
             legend_location = "top",
             title="Avg Ingredients Stacked Bar Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             legend_style={"fill":"black"},
             legend_text={"font-size":"18px"}
      )

fig.layout.width="900px"
fig.layout.height="700px"

bar4.tooltip = Tooltip(fields=['x', 'y'], labels=["WineType", "Avg Ingredient"], formats=["0.1f", "0.2f"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Histogram

The fifth chart type that we'll explain is the histogram. We have followed the same steps as previous charts to create a histogram. We have created LinearScale for both the X and Y-axis. We have used the Hist() constructor for creating a histogram. We have created a histogram of alcohol value distribution. We have also modified various chart attributes to improve the aesthetics of the chart.

In [ ]:
from bqplot import Hist

x_linear = LinearScale()
y_linear = LinearScale()

hist = Hist(sample=wine_df.alcohol, bins=30,
            scales={'sample': x_linear, 'count': y_linear},
            colors=["tomato"], opacities=[0.8])

ax_x = Axis(scale=x_ord, label="Alcohol",
            label_offset="35px",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label="Frequency",
            orientation="vertical", label_offset="35px",
            tick_format="0.1f")

fig = Figure(marks=[hist],
             axes=[ax_x, ax_y],
             legend_location = "top",
             title="Avg Ingredients Stacked Bar Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"gray"}

      )

fig.layout.width="700px"
fig.layout.height="500px"

hist.tooltip = Tooltip(fields=['count'], labels=["Freq"], formats=["0.1f"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Pie Chart

The sixth chart type that we'll introduce plotting using bqplot object model API is a pie chart. We have created pie chart showing the distribution of wine data examples per each category of wine. We have created a pie chart using the Pie() constructor. We have even modified various attributes of the chart to improve chart look and feel like the radius of the circle, the radius of the inner circle, label colors, label size, values format, font-weight, etc.

In [ ]:
from bqplot import Pie
from collections import Counter

wine_type_cnt = Counter(wine_df.WineType)

pie = Pie(sizes=list(wine_type_cnt.values()), labels=list(wine_type_cnt.keys()),
          colors=["tomato", "lime", "dodgerblue"], stroke="black",
          opacities = [0.8, 0.8, 0.8],
          radius=180, inner_radius=80,
          sort=True,
          display_values=True, values_format='0.0f',
          label_color="white", font_size="16px", font_weight="bolder"
          )

fig = Figure(marks=[pie],
             legend_location = "top",
             title="Wine Class Distribution Pie Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"black"}

      )

fig.layout.width="500px"
fig.layout.height="500px"

pie.tooltip = Tooltip(fields=['sizes'], labels=["Count"], formats=["0.1f"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Below we have created another pie chart based on the same data as the previous step with the only difference is that we have not used the whole circle to show distribution. Instead, only 75% of the circle is used for showing distribution. We have modified various chart attributes like the previous steps to improve aesthetics.

In [ ]:
pie = Pie(sizes=list(wine_type_cnt.values()), labels=list(wine_type_cnt.keys()),
          colors=["tomato", "lime", "dodgerblue"], stroke="black",
          opacities = [0.8, 0.8, 0.8],
          radius=180, inner_radius=80,
          start_angle=90, end_angle=360,
          sort=True,
          display_values=True, values_format='0.1f',
          font_size="16px", font_weight="bolder"
          )

fig = Figure(marks=[pie],
             legend_location = "top",
             title="Wine Class Distribution Pie Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"orange"}

      )

fig.layout.width="500px"
fig.layout.height="500px"

pie.tooltip = Tooltip(fields=['sizes'], labels=["Count"], formats=["0.1f"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

BoxPlot

The seventh chart that we'll plot using bqplot is a box plot. We have created another dataframe from the original dataframe by keeping only a few columns that will be used for the box plot chart. We have created the X-axis scale as OrdinalScale because of different columns used for the box plot. The Y-axis scale has been created as LinearScale to show the spread of data of each column. We have created a box plot using the Boxplot() constructor available from bqplot passing scales for both axes. We have also modified various chart attributes like outlier color, line color, box width, background color, grid color, etc.

In [ ]:
from bqplot import Boxplot

mini_df = wine_df[["alcohol","malic_acid","ash","total_phenols", "flavanoids", "nonflavanoid_phenols", "proanthocyanins", "color_intensity", "hue"]]

x_ord = OrdinalScale()
y_linear = LinearScale()

boxplot = Boxplot(x=range(mini_df.shape[1]), y=mini_df.values.T,
                  scales={'x':x_ord, 'y':y_linear},
                  color="lime", names=mini_df.columns,
                  outlier_color="white", stroke="white", box_width=30
                 )


ax_x = Axis(scale=x_ord, label="Ingredients",
            label_offset="35px", grid_color="gray",
            tick_format="0.1f")
ax_y = Axis(scale=y_linear, label="Distribution",
            orientation="vertical", label_offset="35px",
            grid_color="gray",
            tick_format="0.1f")

fig = Figure(marks=[boxplot],
             axes=[ax_x, ax_y],
             title="Avg Ingredients Stacked Bar Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"black"}

      )

fig.layout.height="600px"

boxplot.tooltip = Tooltip(fields=['x'], labels=["Ingredients"])

fig

bqplot - Interactive Charts using Internal Object Model API [Python]

CandleStick

The eighth and last chart that we'll introduce is a candlestick chart. We can create a candlestick chart using the OHLC constructor of bqplot. We have created X-axis as DateScale for dates and Y-axis as LinearScale for price changes. We have created a candlestick chart for apple price only for January-2020. We have also modified various chart attributes like bar colors, bar line colors, background color, grid color, etc. We have used marker as candle to plot the candlestick charts. There is another marker type available called bar which is used to plot the next chart.

In [ ]:
from bqplot import OHLC

apple_df_jan_2020 = apple_df.set_index("Date")["2020-1"]

x_date = DateScale()
y_linear = LinearScale()

ohlc = OHLC(x=apple_df_jan_2020.index, y=apple_df_jan_2020[["Open","High","Low","Close"]],
            scales={'x':x_date, 'y':y_linear},
            marker="candle",
            stroke="dodgerblue", stroke_width=1.0,
            colors=["lime", "tomato"],
            )

ax_x = Axis(scale=x_date, label="Date",
            label_offset="35px", grid_color="gray",
            )
ax_y = Axis(scale=y_linear, label="Price",
            orientation="vertical", label_offset="35px",
            grid_color="gray",
            tick_format="0.1f")

fig = Figure(marks=[ohlc],
             axes=[ax_x, ax_y],
             title="Apple Jan-2020 CandleStick Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
             background_style = {"fill":"black"}
      )

fig.layout.height="600px"


fig

bqplot - Interactive Charts using Internal Object Model API [Python]

Below we have created another candlestick chart which is sometimes referred to as ohlc chart as well. We have used almost the same code as the previous step with one major change which is setting the marker attribute of OHLC() constructor to bar instead of candle.

In [ ]:
x_date = DateScale()
y_linear = LinearScale()

ohlc = OHLC(x=apple_df_jan_2020.index, y=apple_df_jan_2020[["Open","High","Low","Close"]],
            scales={'x':x_date, 'y':y_linear},
            marker="bar",
            stroke="dodgerblue", stroke_width=2.0,
            )

ax_x = Axis(scale=x_date, label="Date",
            label_offset="35px", grid_color="gray",
            )
ax_y = Axis(scale=y_linear, label="Price",
            orientation="vertical", label_offset="35px",
            grid_color="gray",
            tick_format="0.1f")

fig = Figure(marks=[ohlc],
             axes=[ax_x, ax_y],
             title="Apple Jan-2020 CandleStick Chart",
             fig_margin= dict(top=60, bottom=40, left=50, right=20),
      )

fig.layout.height="600px"


fig

bqplot - Interactive Charts using Internal Object Model API [Python]

This ends our small tutorial explaining various chart creation using bqplot's internal object model API. Please feel free to let us know your views in the comments section.

References



Sunny Solanki  Sunny Solanki