Contents

c3py

c3py is a Python wrapper around c3js (http://c3js.org/).

Introduction

c3js has a function named generate, which takes a JSON object as input, and generates a chart which is bound to a specified <div> element. The basic premise of c3py is to build a Python dictionary, which is then converted to a JSON object using json.dumps, and passed to c3.generate().

This works particularly well with Jupyter notebooks, where the HTML function from IPython.display can be used to display the interactive chart inline.

Basic usage

First, import c3py and HTML (from IPython.display).


In [1]:
import c3py
from IPython.display import HTML

Create an instance of the Chart class, providing the chart's name as the lone argument. The name will be the ID of the <div> which contains that chart, i.e. two charts in the same document should not have the same name.


In [2]:
chart_one = c3py.Chart('chart_one')

The chart contains a data object, which has functions analogous to c3js' different chart types. These include:

  • line
  • area
  • bar
  • scatter

Each of these functions takes, as arguments, x and y, which are lists of values, and label, which is a string defining the name of the series.


In [3]:
chart_one.data.line(x=range(1, 6), y=range(10, 60, 10), label='series_one')

Once data has been added, the chart can be displayed in a notebook using the HTML function imported earlier. Alternatively, c3py can be used in a web application, and the HTML string can be passed to the front-end template.


In [4]:
HTML(chart_one.get_html_string())


Out[4]:

Chart types

Line


In [5]:
line_chart = c3py.Chart('line_chart')
line_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')
line_chart.data.line(x=[6, 7, 8, 9, 10], y=[10, 40, 20, 30, 50], step=True, label='step')
line_chart.data.line(x=[11, 12, 13, 14, 15], y=[10, 40, 20, 30, 50], spline=True, label='spline')

HTML(line_chart.get_html_string())


Out[5]:

Marker visibility


In [6]:
no_marker_line_chart = c3py.Chart('no_marker_line_chart')
no_marker_line_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

no_marker_line_chart.point.set_visibility(False)

HTML(no_marker_line_chart.get_html_string())


Out[6]:

Area


In [7]:
area_chart = c3py.Chart('area_chart')
area_chart.data.area(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='area')
area_chart.data.area(x=[6, 7, 8, 9, 10], y=[10, 40, 20, 30, 50], step=True, label='area_step')
area_chart.data.area(x=[11, 12, 13, 14, 15], y=[10, 40, 20, 30, 50], spline=True, label='area_spline')

HTML(area_chart.get_html_string())


Out[7]:

Stacked area


In [8]:
stacked_area_chart = c3py.Chart('stacked_area_chart')
stacked_area_chart.data.area(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='area_one')
stacked_area_chart.data.area(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='area_two')
stacked_area_chart.data.area(x=[6, 7, 8, 9, 10], y=[10, 40, 20, 30, 50], label='area_three')

stacked_area_chart.data.group_series(['area_one', 'area_two'])

HTML(stacked_area_chart.get_html_string())


Out[8]:

Bar


In [9]:
bar_chart = c3py.Chart('bar_chart')
bar_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')

HTML(bar_chart.get_html_string())


Out[9]:

Stacked bar


In [10]:
stacked_bar_chart = c3py.Chart('stacked_bar_chart')
stacked_bar_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar_one')
stacked_bar_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar_two')
stacked_bar_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar_three')

stacked_bar_chart.data.group_series(['bar_one', 'bar_two'])

HTML(stacked_bar_chart.get_html_string())


Out[10]:

Scatter


In [11]:
scatter_chart = c3py.Chart('scatter_chart')
scatter_chart.data.scatter(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='scatter')

HTML(scatter_chart.get_html_string())


Out[11]:

Combination


In [12]:
combination_chart = c3py.Chart('combination_chart')

combination_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')
combination_chart.data.area(x=[1, 2, 3, 4, 5], y=[5, 20, 10, 15, 25], label='area')
combination_chart.data.scatter(x=[6, 7, 8, 9, 10], y=[10, 40, 20, 30, 50], label='scatter')
combination_chart.data.bar(x=[6, 7, 8, 9, 10], y=[5, 20, 10, 15, 25], label='bar')

HTML(combination_chart.get_html_string())


Out[12]:

Axes

X axis type

Category


In [13]:
category_axis = c3py.Chart('category_axis')

category_axis.axes.x_axis.set_type('category')

category_axis.data.bar(x=['a', 'b', 'c', 'd', 'e'], y=[10, 40, 20, 30, 50], label='bar_category')

HTML(category_axis.get_html_string())


Out[13]:

Time series


In [14]:
timeseries_axis = c3py.Chart('timeseries_axis')

timeseries_axis.axes.x_axis.set_type('timeseries')

timeseries_axis.data.line(x=['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04', '2000-01-05'], y=[10, 40, 20, 30, 50], label='line_timeseries')

HTML(timeseries_axis.get_html_string())


Out[14]:

Axis range


In [15]:
axis_range_chart = c3py.Chart('axis_range_chart')

axis_range_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

axis_range_chart.axes.y_axis.set_range_min(0)
axis_range_chart.axes.y_axis.set_range_max(100)
axis_range_chart.axes.x_axis.set_range(-20, 80)

HTML(axis_range_chart.get_html_string())


Out[15]:

Axis padding


In [16]:
axis_padding_chart = c3py.Chart('axis_padding_chart')

axis_padding_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

# y axis padding is in pixels
axis_padding_chart.axes.y_axis.padding.set('bottom', 10)
axis_padding_chart.axes.y_axis.padding.set('top', 20)

# x axis padding is in the unit of the x axis
axis_padding_chart.axes.x_axis.padding.set('right', 5)

HTML(axis_padding_chart.get_html_string())


Out[16]:

Axis label


In [17]:
axis_label_chart = c3py.Chart('axis_label_chart')

axis_label_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

axis_label_chart.axes.y_axis.label.set('y_label')
axis_label_chart.axes.x_axis.label.set('x_label', label_position='inner-right')

HTML(axis_label_chart.get_html_string())


Out[17]:

X axis height


In [18]:
axis_height_chart = c3py.Chart('axis_height_chart')

axis_height_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')

# x axis height is in pixels
axis_height_chart.axes.x_axis.set_height(120)

HTML(axis_height_chart.get_html_string())


Out[18]:

Axis ticks

Tick format

For formatting of numbers, see https://github.com/mbostock/d3/wiki/Formatting.
For formatting of times, see https://github.com/mbostock/d3/wiki/Time-Formatting.


In [19]:
tick_format_chart = c3py.Chart('tick_format_chart')

tick_format_chart.axes.x_axis.set_type('timeseries')

tick_format_chart.data.line(x=['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04', '2000-01-05'], y=[10, 40, 20, 30, 50], label='line_timeseries')

tick_format_chart.axes.x_axis.ticks.set_format('%A %d %B %Y')
tick_format_chart.axes.y_axis.ticks.set_format('$,')

HTML(tick_format_chart.get_html_string())


Out[19]:

Tick count


In [20]:
tick_count_chart = c3py.Chart('tick_count_chart')

tick_count_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

tick_count_chart.axes.y_axis.ticks.set_count(3)
tick_count_chart.axes.x_axis.ticks.set_count(9)

HTML(tick_count_chart.get_html_string())


Out[20]:

Tick values


In [21]:
tick_values_chart = c3py.Chart('tick_values_chart')

tick_values_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

tick_values_chart.axes.y_axis.ticks.set_values([15, 25, 45])
tick_values_chart.axes.x_axis.ticks.set_values([1, 1.5, 2, 4, 5])

HTML(tick_values_chart.get_html_string())


Out[21]:

X tick culling


In [22]:
tick_culling_chart = c3py.Chart('tick_culling_chart')

tick_culling_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

tick_culling_chart.axes.x_axis.ticks.cull(max_ticks=3)

HTML(tick_culling_chart.get_html_string())


Out[22]:

X tick multiline and rotation


In [23]:
tick_multiline_chart = c3py.Chart('tick_multiline_chart')

tick_multiline_chart.axes.x_axis.set_type('category')

tick_multiline_chart.data.bar(x=['longstringsnormallyoccupymultiplelines_' + str(i) for i in range(1, 6)], y=[10, 40, 20, 30, 50], label='bar_category')

tick_multiline_chart.axes.x_axis.ticks.set_multiline(False)
tick_multiline_chart.axes.x_axis.ticks.rotate(90)

HTML(tick_multiline_chart.get_html_string())


Out[23]:

X tick fitting


In [24]:
tick_fitting_chart = c3py.Chart('tick_fitting_chart')

tick_fitting_chart.axes.x_axis.set_type('timeseries')

tick_fitting_chart.data.line(x=['2000-01-01', '2000-02-01', '2000-02-02', '2000-02-03', '2000-02-04'], y=[10, 40, 20, 30, 50], label='line_timeseries')

tick_fitting_chart.axes.x_axis.ticks.set_fit(False)

HTML(tick_fitting_chart.get_html_string())


Out[24]:

Secondary y axis


In [25]:
secondary_axis_chart = c3py.Chart('secondary_axis_chart')

secondary_axis_chart.axes.add_secondary_y()

secondary_axis_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='primary_y_axis', axis='y')
secondary_axis_chart.data.line(x=[1, 2, 3, 4, 5], y=[5, 3, 2, 4, 1], label='secondary_y_axis', axis='y2')

secondary_axis_chart.axes.y2_axis.set_range(-10, 10)
secondary_axis_chart.axes.y2_axis.ticks.set_format('.2f')

HTML(secondary_axis_chart.get_html_string())


Out[25]:

Grid

Grid visibility


In [26]:
grid_visibility_chart = c3py.Chart('grid_visibility_chart')

grid_visibility_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')

grid_visibility_chart.grid.show(x=False, y=True)

HTML(grid_visibility_chart.get_html_string())


Out[26]:

Custom grid lines


In [27]:
grid_line_chart = c3py.Chart('grid_line_chart')

grid_line_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

grid_line_chart.grid.custom_grid_line(axis='x', value=2.5, label='x_grid_line')
grid_line_chart.grid.custom_grid_line(axis='y', value=15, label='y_grid_line', label_position='start')

HTML(grid_line_chart.get_html_string())


Out[27]:

Legend

Legend visibility


In [28]:
legend_visibility_chart = c3py.Chart('legend_visibility_chart')

legend_visibility_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')

legend_visibility_chart.legend.hide()

HTML(legend_visibility_chart.get_html_string())


Out[28]:

Series visibility


In [29]:
legend_series_visibility_chart = c3py.Chart('legend_series_visibility_chart')

legend_series_visibility_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')
legend_series_visibility_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

legend_series_visibility_chart.legend.hide_series(['line'])

HTML(legend_series_visibility_chart.get_html_string())


Out[29]:

Legend position


In [30]:
legend_position_chart = c3py.Chart('legend_position_chart')

legend_position_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')
legend_position_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

legend_position_chart.legend.set_position('inset', inset_anchor='top-left')

HTML(legend_position_chart.get_html_string())


Out[30]:

Tooltip

Tooltip visibility


In [31]:
tooltip_visibility_chart = c3py.Chart('tooltip_visibility_chart')

tooltip_visibility_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

tooltip_visibility_chart.tooltip.hide()

HTML(tooltip_visibility_chart.get_html_string())


Out[31]:

Tooltip grouping


In [32]:
tooltip_grouping_chart = c3py.Chart('tooltip_grouping_chart')

tooltip_grouping_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line_one')
tooltip_grouping_chart.data.line(x=[1, 2, 3, 4, 5], y=[5, 20, 10, 15, 25], label='line_two')

tooltip_grouping_chart.tooltip.ungroup()

HTML(tooltip_grouping_chart.get_html_string())


Out[32]:

Tooltip title


In [33]:
tooltip_title_chart = c3py.Chart('tooltip_title_chart')

tooltip_title_chart.data.bar(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='bar')

tooltip_title_chart.tooltip.tooltip_format.set_title('"value on x axis = " + x')

HTML(tooltip_title_chart.get_html_string())


Out[33]:

Regions


In [34]:
regions_chart = c3py.Chart('regions_chart')

regions_chart.data.line(x=[1, 2, 3, 4, 5], y=[10, 40, 20, 30, 50], label='line')

regions_chart.regions.add(name='x_region', axis='x', start=2, end=4, color='red')
regions_chart.regions.add(name='y_region', axis='y', start=40, end=50, color='green')

HTML(regions_chart.get_html_string())


Out[34]:

In [36]:
%%javascript

$.each($(":header"), function(index, value) {
    value.id = value.innerText.replace(/\s+/g, '').toLowerCase();
    var heading_level = parseInt(value.localName.charAt(1));
    $("#table_of_contents").append(Array((heading_level - 1) * 6).join("&nbsp;") + "<a href='#" + value.id + "'>" + value.innerText + "</a><br />");
});