[PYTHON] High charts on Jupyter notebook

What is Highcharts

A visualization library that works with Javascript. It has the following functions / features.

It is very sophisticated, but there is a charge for commercial use.

Why Highcharts?

beautiful

As you can see from the sample on the Official Site, you can draw a beautiful and cool graph without any ingenuity.

Light

It is a detonation velocity. As a sample, let's draw a scatter plot in which 1000 points as shown below are color-coded into 7 groups.

import numpy as np
import pandas as pd

num = 1000
x, y = np.random.random((2, num))
labels = np.random.choice(['a', 'b', 'c', 'e', 'f', 'g', 'h'], num)
df = pd.DataFrame(dict(x=x, y=y, label=labels))

Let's compare it with the following three typical libraries.

  1. Matplotlib
  2. Bokeh
  3. Plotly

Matplotlib

import matplotlib.pyplot as plt
groups = df.groupby('label')
colors = 'bgrcmyk'
for i, (name, group) in enumerate(groups):
    plt.scatter(group.x, group.y, color=colors[i])

Bokeh

from bokeh.charts import Scatter, output_notebook, show
output_notebook()
show(Scatter(x='x', y='y', color='label', data=df))

Plotly

from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()
groups = df.groupby('label')
data = [{'x': group.x, 'y': group.y, 'mode': 'markers', 'name': name} for name, group in groups]
fig = {'data': data}
iplot(fig)

Highcharts

from highcharts import Highchart

groups = df.groupby('label')
options = {
    'chart': {
        'type': 'scatter',
    },
}
H = Highchart()
H.set_dict_options(options)
for name, group in groups:
    data = list(zip(group.x, group.y))
    H.add_data_set(data, 'scatter', name)
H

The result looks like this.

Including import (initialization)

benchmark01.png

import (initialization) not included

benchmark02.png

There are many possible reasons, but it's light.

%% html implemented with magic

Highcharts is a JavaScript library, so you need to make some ingenuity to use it with Jupyter notebook. There is a way to use a template engine etc., but as a simple example, let's use %% html magic.

from IPython.display import HTML
%%html
    <script src="http://code.highcharts.com/highcharts.js"></script>
    <script src="http://code.highcharts.com/modules/exporting.js"></script>
    <div id="container" style="width:300px; height:200px;"></div>
    <script>
        plot = function () { 
            $('#container').highcharts({
                chart: {
                    type: 'line'
                },
                series: [{
                    data: [1, 2, 3]
                }]
            });
        };
        plot();
    </script>

htmlmagic.png

Implemented with python-highchart

In the %% html magic mentioned above, you're just writing JavaScript, not Python. Furthermore, when you want to handle variables, you need to use a template engine etc., which is troublesome.

So, let's use python-highcharts, which can call Highcharts from Python.

Installation

You can install it with pip.

pip install python-highcharts

Line graph

If you implement the same line graph implemented by %% html magic mentioned above with python-highcharts, it will be as follows.

from highcharts import Highchart

H = Highchart(width=300, height=200)
H.add_data_set([1, 2, 3])
H

It's very clean and can now be written in Python.

Graph options

For the appearance of the graph, pass the dictionary type value to highcharts.Highchart.set_options (). See the Highcharts Reference (http://api.highcharts.com/highcharts) for possible values.

from highcharts import Highchart

H = Highchart(width=300, height=200)
options = {
    'title': {
        'text': 'Main title'
    },
    'subtitle': {
        'text': 'subtitle'
    },
    'xAxis': {
        'title': {'text': 'X axis'}
    },
    'yAxis': {
        'title': {'text': 'Y axis'},
        'lineWidth': 2
    },
}
H.set_dict_options(options)
H.add_data_set([1, 2, 3])
H

options.png

It is also possible to set for each individual parameter. This may be more readable.

from highcharts import Highchart

H = Highchart(width=300, height=200)
H.set_options('title', {'text': 'Main title'})
H.set_options('subtitle', {'text': 'subtitle'})
H.set_options('xAxis', {'title': {'text': 'X axis'}})
H.set_options('yAxis', {'title': {'text': 'Y axis'}, 'lineWidth': 2})
H.add_data_set([1, 2, 3])
H

The appearance of the element is set with highcharts.Highchart.add_data_set ().

from highcharts import Highchart

H = Highchart(width=300, height=200)
H.add_data_set([1, 2, 3], dashStyle='ShortDash', color='plum', lineWidth=6)
H

glyph.png

Graph type

Specify the graph type in the second argument of highcharts.Highchart.add_data_set (). The specification of each position parameter is as follows.

Positional parameters object Mold
1 data set List, tuple
2 Graph type String
3 name String

In the example below, the first element outputs an area chart named data1 and the second element outputs a bar graph named data2.

from highcharts import Highchart

H = Highchart(width=300, height=200)
H.add_data_set([1, 2, 3], 'area', 'data1')
H.add_data_set([4, 5, 6], 'bar', 'data2')
H

bar.png

Drill down

Clicking on a graph element will bring up another graph ... and so on.

Pass dictionary data to each element of highcharts.Highchart.add_data_set (). Set the dictionary key to drilldown and the value to the name corresponding to the drilldown.

To specify the element after drilling down, specify the three arguments of the position parameter described above in highcharts.Highchart.add_drilldown_data_set (). Make the third name correspond to the higher element.

from highcharts import Highchart

H = Highchart(width=400, height=200)
data = [{
    'y': 1,
    'drilldown': 'a'
}, {
    'y': 2,
    'drilldown': 'b'
}, {
    'y': 3,
    'drilldown': 'c'
}]
H.add_data_set(data, 'column')
H.add_drilldown_data_set([0.3, 0.4, 0.3], 'pie', 'a')
H.add_drilldown_data_set([4, 5, 6], 'line', 'b')
H.add_drilldown_data_set([7, 8, 9], 'area', 'c')
H

drilldown.gif

Bonus (Yakiu hack)

As an example of using drill down, let's create a graph that displays the number of wins of 12 professional baseball teams in 2016 on a bar graph, and clicks each element to output the number of wins of the pitcher.

import pandas as pd
from highcharts import Highchart


class Team:
    def __init__(self):
        self.team_names = ['Hawks', 'Fighters', 'Marines', 'Lions',
                           'Buffaloes', 'Eagles', 'Swallows', 'Giants',
                           'Tigers', 'Carp', 'Dragons', 'BayStars']
        self.urls = [self.make_url(x) for x in self.team_names]
        self.dfs = [self.load_pitcher_win_data(url) for url in self.urls]
        self.wins = [df['win'].sum() for df in self.dfs]
        self.team_data = [
            self.make_y_dict(team_name, wins)
            for team_name, wins in zip(self.team_names, self.wins)
        ]
        self.pitcher_data = [df.values.tolist() for df in self.dfs]

    def make_url(self, team_name):
        def join_url(x):
            return ''.join(('http://npb.jp/bis/2016/stats/idp1_', x, '.html'))

        if team_name == 'Buffaloes':
            return join_url('bs')
        elif team_name == 'BayStars':
            return join_url('db')
        else:
            return join_url(team_name[0].lower())

    def load_pitcher_win_data(self, url):
        tables = pd.read_html(url)
        df = tables[0].iloc[2:, [1, 3]]
        df.columns = ['pitcher', 'win']
        df['win'] = df['win'].astype(float)
        return df[df['win'] > 0]

    def make_y_dict(self, team_name, wins):
        return {'name': team_name, 'y': wins, 'drilldown': team_name}

t = Team()

options = {
    'chart': {
        'type': 'column'
    },
    'title': {
        'text': '2016 wins'
    },
    'subtitle': {
        'text': 'Click the columns to view pitchers.'
    },
    'xAxis': {
        'type': 'category'
    },
    'yAxis': {
        'title': {
            'text': 'win'
        }
    },
    'legend': {
        'enabled': False
    },
    'plotOptions': {
        'series': {
            'borderWidth': 0,
            'dataLabels': {
                'enabled': True,
            }
        }
    },
    'tooltip': {
        'headerFormat':
        '<span style="font-size:11px">{series.name}</span><br>',
    },
}


H = Highchart(width=850, height=400)
H.set_dict_options(options)
H.add_data_set(t.team_data, 'column', "Team", colorByPoint=True)
for i, team_name in enumerate(t.team_names):
    H.add_drilldown_data_set(
        t.pitcher_data[i], 'column', team_name, name=team_name)
H

baseball.gif

Implemented with pandas-highcharts

Installation

You can install it with pip.

pip install pandas-highcharts

As the name implies, it draws pandas DataFrames with Highcharts. You can output a graph just by passing the same arguments as pandas.DataFrame.plot () to pandas_highcharts.display.display_charts.

import pandas as pd
from pandas_highcharts.display import display_charts

df = pd.DataFrame([1, 2, 3], index=[list('abc')])
display_charts(df, figsize=(300, 200))

pandas01.png

Specifying the graph type is the same as pandas.

import pandas as pd
from pandas_highcharts.display import display_charts

df = pd.DataFrame([1, 2, 3], index=[list('abc')])
display_charts(df, kind='bar', figsize=(300, 200))

pandas02.png

In terms of functionality, python-highcharts is more abundant, but if you want to visualize pandas data, this is easier.

Recommended Posts

High charts on Jupyter notebook
View PDF on Jupyter Notebook
Run Jupyter Notebook on windows
Formatting with autopep8 on Jupyter notebook
Run azure ML on jupyter notebook
Try running Jupyter Notebook on Mac
Write charts in real time with Matplotlib on Jupyter notebook
Jupyter Notebook memo
Introducing Jupyter Notebook
Make Jupyter Notebook a service on CentOS
Try SVM with scikit-learn on Jupyter Notebook
Powerful Jupyter Notebook
Start jupyter notebook on GPU server (remote server)
Golang on jupyter
Clone the github repository on jupyter notebook
Jupyter on AWS
GPU check of PC on jupyter notebook
Display histogram / scatter plot on Jupyter Notebook
Build jupyter notebook on remote server (CentOS)
Jupyter notebook password
Use vim keybindings on Docker-launched Jupyter Notebook
Jupyter Notebook memo
Run Jupyter notebook on a remote server
Install matplotlib and display graph on Jupyter Notebook
[Jupyter Notebook / Lab] 3 ways to debug on Jupyter [Pdb]
[Pythonocc] I tried using CAD on jupyter notebook
Simply display a line graph on Jupyter Notebook
Try Apache Spark on Jupyter Notebook (on local Docker
Remotely open Jupyter notebook launched on the server
jupyter notebook does not start on mac fish
Hello X3DOM on Jupyter
Get started Jupyter Notebook
3 Jupyter notebook (Python) tricks
[Cloud103] # 3 Jupyter Notebook again
Run Tensorflow from Jupyter Notebook on Bash on Ubuntu on Windows
Monitor the training model with TensorBord on Jupyter Notebook
Try basic operations for Pandas DataFrame on Jupyter Notebook
EC2 provisioning with Vagrant + Jupyter (IPython Notebook) on Docker
[Windows] [Python3] Install python3 and Jupyter Notebook (formerly ipython notebook) on Windows
How to view progress bar on Jupyter Notebook to see progress
Install octave_kernel on Jupyter [additional]
Shortcut key for Jupyter notebook
Run Jupyter on Ubuntu on Windows
Introduced Jupyter Notebook to CentOS 7
Using Graphviz with Jupyter Notebook
[Memo] Display Jupyter Notebook on PC in monospaced font (Mac)
Display HTML in Jupyter notebook
Use pip with Jupyter Notebook
Multiprocessing error in Jupyter Notebook
Smoothly reload modules on jupyter
Displaying strings on IPython Notebook
Try using Jupyter Notebook dynamically
[Super Basics] About jupyter Notebook
Use Cython with Jupyter Notebook
homebrew, pyenv, anaconda, Jupyter Notebook
Play with Jupyter Notebook (IPython Notebook)
Label images on jupyter lab
[Complete version] Jupyter Notebook shortcut
Unable to display tensorboard in jupyter notebook on docker (solved)
Run IPython Notebook on Docker
A very convenient way to give a presentation on Jupyter Notebook