I’m a regular Plotly.py user for over a year and I love it, but, this setup allows to publish at online at most 25 charts. I’ve been looking for a free alternative to create customized, interactive charts, which can be easily embedded on the website. Bellow, I’ll compare C3.js and Plotly.js as an alternative.

D3.js and it’s children

According to its website, D3.js is a library which allows you to bind arbitrary data to a Document Object Model (DOM), and then apply data-driven transformations to the document. Among other things it allows to create powerful visualizations however, the code is long and hard to read. Both Plotly and C3.js are libraries built on the top of D3.js, dedicated to creating charts.

Plotly is a graphing tool created by a private company. It’s available for different languages. I love Plotly for classy domain visual effects and user-friendly syntax. I’ll use the term Plotly.py when referred to Plotly as Python library and Plotly.js as JavaScript library. Plotly.py allows embedding at most 25 interactive charts on the website. The JavaScript library is open source and allows to embed unlimited interactive charts.

C3.js is an open source library, which has user-friendly wrap-ups for D3.js plotting functions. I decided to at first try out C3.js instead of other graphing libraries because it’s highly customizable, interactive and free. The most suitable to my needs.

Practical test

You can find many theoretical comparisons of Plotly and C3.js. I decided to test them in the action:

  • I created a customized chart in Plotly.py in Jupyter notebook (it’s fast and easy)
  • I tried to reproduce it using Plotly.js
  • I tried to reproduce it using C3.js

I focused on the following aspects:

  • the quality of the basic chart (with predefined visual effects)
  • limitations when trying to create an identical chart
  • the number of code lines required to create an identical chart
  • readability
  • size of libraries

Chart to reproduce

The chart (bar+line) to reproduce was designed in Jupyter Notebook using Plotly.py. I’ve used fake data to focus on the appearance. 

The chart has customized features:
  • Colors
  • Font
  • Second axis with the scope starting from 0
  • Line and marker thickness
  • Legend position

Plotly.js

Default style

As mentioned, Plotly.js is open source so it could be an alternative to Plotly.py. The basic chart is modern and eye-catching however, the predefined layout  has some defects:

  • The legend is overlaying the second axis
  • By default, the grid is displayed for both axes which are misleading and unaesthetic
<div class="chart_box">
<div id="Plotly_Basic" class="chart_inside_box"></div>
<script>
CHART = document.getElementById('Plotly_Basic');
var BAR = {x: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 
           y: [0,1,2,4,6,10], name:'y1', type : 'bar'
     };
var LINE = {x: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 
           y: [100, 110, 115, 100, 95, 105], 
           name:'y2', type: 'scatter',  yaxis: 'y2'
     };
var LAYOUT = {autosize:true, title: "Title", 
           yaxis1 : {title: "Title of Y1"}, 
           yaxis2 : {title: "Title of Y2", overlaying: 'y',side: 'right'}
     };
var FIG = {data : [BAR, LINE], layout : LAYOUT};
Plotly.plot( CHART, FIG);
</script>
</div>

 

Custom style

The custom layout was added directly in the script. The following changes have been made: custom color and font, a grid for only left axis, rescaled right axis, legend position. The final Plotly.js chart is identical to the one made in Plotly.py (exception – the black x axis line is missing even though it’s visible when loaded from single HTML file):

 

<div class="chart_box">
<div id="Plotly_Customized" class="chart_inside_box"></div>
<script>
CHART = document.getElementById('Plotly_Customized');
var BAR = {x: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 
           y: [0,1,2,4,6,10], 
           name:'y1', type : 'bar', marker: {color: '#de6e4b'}
    }; 
   
var LINE = {x: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 
           y: [100, 110, 115, 100, 95, 105], 
           name:'y2', type: 'scatter', marker: {color: '#7a6563', size : 9}, line : {width : 5}, yaxis: 'y2'
    };
var LAYOUT = {autosize:true, title: "Title", font:{family: 'Playfair Display','size' : 16}, 
           yaxis1 : {title: "Title of Y1", rangemode : 'tozero'}, 
           yaxis2 : {title: "Title of Y2", rangemode : 'tozero', overlaying: 'y',side: 'right', showgrid: false, range: [0,120]}, 
           legend: {orientation: "h", yanchor:'top',xanchor:'center',y:-0.1, x:0.5}
    }; 
var FIG = {data : [BAR, LINE], layout : LAYOUT};
Plotly.plot( CHART, FIG);
</script>
</div>

 

C3.js

Default style

C3.js basic chart is old fashioned. It has no default title. Compared to Plotly, the latter one has well predefined the details. The bar width, line thickness, font, axis, proportions define the modern style of Plotly. As a result, it requires more effort to design appealing charts in C3.js.

<div class="chart_box">
<div id="C3_basic" class="chart_inside_box"></div>
<script>
var chart = c3.generate({bindto: '#C3_basic',data: {columns: [['y1', 0,1,2,4,6,10],['y2', 100, 110, 115, 100, 95, 105]], axes : {y1: 'y',y2: 'y2'}, types: {y1: 'bar',y2: 'line'}}, axis: { x: {type: 'category', categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']}, y: {label : {text: 'Title of Y1' } ,tick : { values: [2,4,6,8,10]}}, y2: {show: true, label : {text: 'Title of Y2'}, tick : {values: [20,40,60,80,100,120]}} }});
</script>
</div>

 

Custom style

The customized chart is shown below. Some layout properties are added in C3_vs_Plotly_05_2019_c3_custom.css, so they can be imported in the future.  The final chart is almost identical to the basic one. If you’d like to add custom style, create a custom class (ex. C3Customized) which will be added to both <svg> containing the chart and <div> containing the <svg>. Then create CSS styles applying only to objects with your custom class (see C3_vs_Plotly_05_2019_c3_custom.css). Also, if you’d like to link to a custom CSS file, add CSS version in the comment in the file and also in the link including CSS file. Otherwise, WordPress could add it’s own version number and the file could not be found.

<div class="chart_box">
<div id="C3_Customized_1" class="chart_inside_box C3Customized"></div>
<script>var chart = c3.generate({ bindto: '#C3_Customized_1',transition: {duration: 0},data: {columns: [['y1', 0,1,2,4,6,10] ,['y2', 100, 110, 115, 100, 95, 105]], axes : {y1: 'y',y2: 'y2'}, types: {y1: 'bar',y2: 'line'},colors:{y1: '#de6e4b',y2: '#7a6563'}},bar: {width: {ratio: 0.8 }}, point: {r: 6}, grid: {y: { show: true}}, axis: { x: {type: 'category',categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], tick : {outer : false}} , y: {label : { text: 'Title of Y1',position: 'outer-middle' }, tick : {values: [2,4,6,8,10]}}, y2: { label : {text: 'Title of Y2', position: 'outer-middle' }, tick : {values: [20,40,60,80,100,120]}, show: true, min : 10}}});
chart.attr('class', 'C3Customized')
</script>

</div>

 

 

If the layout is likely to be reused, it can be saved and called as a function. Example: function drawBarLinesChart in C3_vs_Plotly_05_2019_custom_functions.js. Below is the basic chart with predefined styles:

<div class="chart_box">
<div id="C3_Customized_2" class="chart_inside_box C3Customized"></div>
<script>drawBarLinesChart("#C3_Customized_2", "C3Customized", [0,1,2,4,6,10], [100, 110, 115, 100, 95, 105], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 'Title of Y1', 'Title of Y2', 450, 750);</script>
</div>

 

Sum up

Both Plotly js. And C3.js allows creating highly customizable charts. None of them required any workarounds. The code is readable and similar length for both Plotly.js and C3.js. For both libraries, the chart and layout can be defined in function which reduces the amount of code and makes it concise. Although there are some differences worth to be mentioned:

Pros + Cons –
  • Pretty domain style
  • Include zooming in a domain style
  • The library is much heavier (~3Mb)
  • Worst appearance for mobile layout
C3.js
  • Light (~0.4Mb)
  • Old-fashioned domain style