<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 First step
In this tutorial we will use Brython, an implementation of Python written in javascript and Python, to access the Highcharts javascript library and to manage the data to be used in the maps. To integrate Brython in the IPython notebook we are using an extension for the notebook called brythonmagic that provides a new magic cell, <code style="background-color
Step1:  And the brython js lib
Step2:  [It is highly recommended that, at least, you read the brythonmagic docs to understand what it does. It is also recommended to have a quick look at the Brython docs].
Warning
In order to load javascript libraries in a safety way you should try to use https instead of http when possible (read more here). If you don't trust the source and/or the source cannot be loaded using https then you could download the javascript library and load it from a local location.
Conventions used in the following tutorial.
In the following tutorial I will try to follow several conventions to try to make it more readable.
Code in cells that are not code cells
Step4:  First example
Step5:  Now the interesting part. To make Highcharts available to Brython we need to 'load' the Highchart object/namespace to Brython using <code style="background-color
Step7:  Pretty simple!!
Ok, let's dissect the code in the Brython cell above.
<code style="background-color
Step8:  I got it!!! It's the ugliest chart in the world!!!
Defining options for all the charts
If we want we can define some of the options to be used during a complete session so we don't have to define each of the options when defining a new chart.
We will use <code style="background-color
Step10:  And now, let's repeat our first example again after the global configuration
Step12:  Much better than the ugly chart. 
And other simple charts will look like the following
Step14:  <span style="background-color
Step16:  An array of arrays with two values. In this case, the first value is the x value and the second is the y value. If the first value is a string, it is applied as the name of the point, and the x value is incremented following the above rules and the string will be used in the tooltip of the point. For range series, the arrays will be interpreted as [x, low, high]. In this cases, the x value can be skipped altogether to make use of pointStart and pointRange.
This way has been used in the scatter chart previously. In the example above we have seen that the x values start at 0. If we want a different behaviour we could define the x values as follows
Step18:  If the x values are not a valid number it will be used as a label in the tooltip and the x values will start by 0 and incrementing by 1. For example
Step20:  An array of objects with named values. In this case the objects are point configuration objects. Range series values are given by low and high.
This is the most complete case as you can define more precisely how the data is displayed.
[HINT] In the next chart we will use the 'bubble' chart type. We must load a new javascript file as the highcharts.js doesn't provide the complete functionality of Highcharts and some type of charts (like 'arearange', 'bubble',...) are included as extras. The new javascript file is highcharts-more.js.
Step22:  On each data value we have used a name (shown in the tooltip), a color (used in scatter, bar, column, bubble,..., charts but not in line or area charts, for example) and the x and y values.
Types of charts
Line charts
We already have seen several line charts. Let's see something more advanced. In the following example we will include the data value for each record and we will be able to choose an area of the chart to zoom on the chosen subset.
Step24:  <span style="background-color
Step26:  <span style="background-color
Step28:  <span style="background-color
Step30:  <span style="background-color
Step32:  <span style="background-color
Step34:  <span style="background-color
Step36:  Column and bar charts
A bar plot with positive and negative values
Step38:  <span style="background-color
Step40:  <span style="background-color
Step42:  <span style="background-color
Step44:  A bubble plot with different colors depending on the size for each record would be as follows
Step45:  3d Charts
For this examples we should first load the 3d highcharts library
Step47:  With the 3d 'module' loaded we can see a new example where some interactivity is added
Step48:  <span style="background-color
Step50:  A simple heatmap would be as follows
Step52:  <span style="background-color
Step54:  Ok, not very exciting. We initialise with an empty dictionary of options and with the show method we pass the options dictionary to Highcharts and we can plot an empty chart. As stated before, not very fascinating. Let's add options to include a title and a subtitle.
[HINT] The -s option in brythonmagic is used to name a brython cell ('wrapper01' is the name for the portion of code defined in the first cell of this section). With the name of that cell the code of the cell can be used in a new Brython cell using the -S option. The use of the -S option would be like an import of the code of the cell with the defined name ('wrapper01' in this case).
Step56:  Still not very funny. If you see the two new methods added, title and subtitle, there is one line commented. We can uncomment these lines if we don't want to call the show method but everytime we use a method the chart will be plotted. I didn't see any overhead doing this but let's avoid it for the moment.
Ok, let's do something more interesting plotting some data in a line chart.
Step58:  Wow!!, with less than 40 lines of Brython code we have a wrapper to do very simple interactive charts using Highcharts in a pythonic way. We added the label keyword in the plot method. In Matplotlib, the label is used by the legend in the case we want to add a legend. Let's add a legend method to provide the label keyword some utility.
Step60:  The behaviour is not similar to that in the pyplot module of the matplotlib library but we can get some basic functionality. We can add a scatter method to combine line plots with scatter plots.
<ASSISTANT_TASK:>
Python Code:
%load_ext brythonmagic
Explanation: First step
In this tutorial we will use Brython, an implementation of Python written in javascript and Python, to access the Highcharts javascript library and to manage the data to be used in the maps. To integrate Brython in the IPython notebook we are using an extension for the notebook called brythonmagic that provides a new magic cell, <code style="background-color: cyan;">%%brython</code>, that allow us to write and execute Brython code in the notebook.
Installation of the brythonmagic IPython extension
As stated before, we will use Brython, and brythonmagic so first of all we need to load the extension and the Brython library.
So, let's load the extension:
End of explanation
from brythonmagic import load_brython_dev
load_brython_dev()
Explanation: And the brython js lib:
End of explanation
from brythonmagic import load_js_lib
load_js_lib("https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/highcharts.js")
Explanation: [It is highly recommended that, at least, you read the brythonmagic docs to understand what it does. It is also recommended to have a quick look at the Brython docs].
Warning
In order to load javascript libraries in a safety way you should try to use https instead of http when possible (read more here). If you don't trust the source and/or the source cannot be loaded using https then you could download the javascript library and load it from a local location.
Conventions used in the following tutorial.
In the following tutorial I will try to follow several conventions to try to make it more readable.
Code in cells that are not code cells:
a block of code will appear as follows:
```python
This is a block of code
print("Hello world!")
```
Python/Brython code commented in a line of text will appear as follows, <code style="background-color: cyan;">this is a piece of Python/Brython code inline with the text</code>
Javascript code commented in a line of text will appear as follows, <code style="background-color: yellow;">this is a piece of javascript code inline with the text</code>
Most of new code used in a code cell will be commented in a paragraph starting with <span style="background-color: #90EE90">[NEW CODE]</span>
When the Python and the javascript code is not exactly the same I will try to comment how the code would be in javascript.
What is Highcharts?
Highcharts is an open source, client side JavaScript library for making interactive charts, viewable in nearly any modern web browser. Since it is a client side library, it requires no special server side software or settings — you can use it without even downloading anything!
This tutorial just try to explain a little bit what can be found in the official documentation and try to introduce this library to Python users.
The website for Highcharts is located at http://www.highcharts.com/. To begin, we need to download a copy of Highcharts (or, we can directly link to the library — this is what we will do in the present tutorial). You can download the compressed library as a .zip file.
So, before continuing let's load the Highcharts library.
End of explanation
html = <div id="hc_ex1" style="width: 700px; height: 300px;"></div>
Explanation: First example: A simple line chart
First we create some simple HTML code. This HTML code will contain our chart. We will not use complicated HTML code during the tutorial to keep it simple and to be focused in 'How to create interactive charts in the browser with Python'. There is a lot of amazing resources to learn about HTML and CSS.
End of explanation
%%brython -h html -p
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart':{
        'renderTo': 'hc_ex1'
    },
    'title': {
        'text': 'Monthly Average Temperature',
        'x': -20 #center
    },
    'subtitle': {
        'text': 'Source: WorldClimate.com',
        'x': -20
    },
    'xAxis': {
        'categories': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },
    'yAxis': {
        'title': {
            'text': 'Temperature (°C)'
        },
        'plotLines': [{
            'value': 0,
            'width': 1,
            'color': '#808080'
        }]
    },
    'tooltip': {
        'valueSuffix': '°C'
    },
    'legend': {
        'layout': 'vertical',
        'align': 'right',
        'verticalAlign': 'middle',
        'borderWidth': 0
    },
    'series': [{
        'name': 'Tokyo',
        'data': [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
    }]
}
hc(config)
Explanation: Now the interesting part. To make Highcharts available to Brython we need to 'load' the Highchart object/namespace to Brython using <code style="background-color: cyan;">Highcharts = window.Highcharts</code>. We will use the <code style="background-color: cyan;">new</code> method injected by Brython to the Javascript object that would behave similarly as if we were using Javascript constructors, (ie functions used with the Javascript keyword <code style="background-color: yellow;">new</code>).
The code is as follows:
End of explanation
html = <div id="hc_ex2" style="width: 700px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart': {
        'renderTo': 'hc_ex2',
        'backgroundColor': {
            'linearGradient': [0, 0, 500, 500],
            'stops': [[0, 'rgb(255, 255, 255)'],
                      [1, 'rgb(200, 200, 255)']]
        },
        'borderRadius': 10
    },
    'title': {
        'align': 'left',
        'text': 'My dummy title',
        'style': { "color": "green", "fontSize": "20px" }
    },
    'subtitle': {
        'align': 'right',
        'text': 'Ugly subtitle',
        'style': { "color": "orange", "fontSize": "12px" }
    },
    'legend': {
        'backgroundColor': 'green',
        'borderColor': 'yellow',
        'borderRadius': 10,
        'borderWidth': 3,
    },
    'series': [{
        'data': [1,2,3,4],
        'type': 'line',
        'name': 'Name of the series',
        'color': 'orange',
    }],
    'tooltip': {
        'backgroundColor': 'gray',
        'borderColor': 'yellow',
        'borderRadius': 10,
        'borderWidth': 3,
    },
    'xAxis': {
        'categories': ['data'] * 4,
        'lineWidth': 5,
        'lineColor': 'violet',
        'gridLineColor': 'violet',
        'gridLineWidth': 3,
        'title': {'text': 'X axis title'}
    },
    'yAxis': {
        'lineWidth': 5,
        'lineColor': 'blue',
        'gridLineColor': 'blue',
        'gridLineWidth': 3,
        'title': {'text': 'Y axis title'}
    },
    'credits': {
        'text': "Pybonacci rules!",
        'href': 'https://twitter.com/pybonacci'
    }
}
hc(config)
Explanation: Pretty simple!!
Ok, let's dissect the code in the Brython cell above.
<code style="background-color: cyan;">%%brython -h html -p</code> :
Indicates that the code cell is written using Brython and we use some options for the Brython code cell, -h to use the HTML code defined in the html variable located in the cell above and -p to print the final HTML code generated below the generated chart. In this example, the generated code should be something like the following:
```html
<script id="66406" type="text/python">
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart':{
        'renderTo': 'hc_ex1'
    },
    'title': {
        'text': 'Monthly Average Temperature',
        'x': -20 #center
    },
    'subtitle': {
        'text': 'Source: WorldClimate.com',
        'x': -20
    },
    'xAxis': {
        'categories': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },
    'yAxis': {
        'title': {
            'text': 'Temperature (°C)'
        },
        'plotLines': [{
            'value': 0,
            'width': 1,
            'color': '#808080'
        }]
    },
    'tooltip': {
        'valueSuffix': '°C'
    },
    'legend': {
        'layout': 'vertical',
        'align': 'right',
        'verticalAlign': 'middle',
        'borderWidth': 0
    },
    'series': [{
        'name': 'Tokyo',
        'data': [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
    }]
}
hc(config)
  </script>
<div id="brython_container_66406"><div id="hc_ex1" style="width: 700px; height: 300px;"></div></div>
<script type="text/javascript">brython({debug:1, static_stdlib_import: false, ipy_id: ["66406"]});</script>
```
the -p option only provides information and it isn't required to run the Brython code cell.
<code style="background-color: cyan;">hc = Highcharts.Chart.new</code>
Here we are instantiating the chart, i.e., accessing the function to the Brython namespace.
<code style="background-color: cyan;">config = { ... }</code>
Here we are defining the options and data to be used in the chart. More on this later.
<code style="background-color: cyan;">hc(config))</code>
We call the hc function with the data and configuration options defined in the config dict.
Configuring Highcharts
We can configure how the chart will be shown, layout, dimensions, axis, titles, legends,... All this information can be managed on each plot or using a configuration object (in javascript or dictionary in Python).
In the previous example we have seen the config dict. Let's dedicate some time to understand it. The config dict contains a series of dicts and each of these dicts manage several pieces of the chart:
chart dict (complete api): It contains information related with how the chart is presented (background colors, area plot colors, type of chart to be used, where the chart should be rendered (html element), margins and spacings,...). A more complete example would be something like the following:
python
'chart': {
    'renderTo': 'The_id_of_the_html_element',
    'backgroundColor': 'a_valid_html_object',
    'type': 'spline',
    'plotBorderWidth': 1,
    'plotBorderColor': '#3F4044',
    ...
}
colors key: The value is a list of strings containing valid html colors. The default colors in the latest highcharts version are:
python
'colors': ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9', 
           '#f15c80', '#e4d354', '#8085e8', '#8d4653', '#91e8e1']
credits dict (complete api): This dict allows you to control the credits label in the chart. By default will be shown the credits in the bottom left area of the chart. To control the credits you can use the following:
python
'credits': {
    'enabled': Boolean,
    'href': String,
    'text': String,
    ...
}
legend dict (complete api): This dict allows you to control how the legend is shown:
python
'legend': {
    'enabled': Boolean,
    'align': String,
    'backgroundColor': String,
    ...
}
plotOptions dict (complete api): The plotOptions dict is a wrapper object for config objects for each series type. The config objects for each series can also be overridden for each series item as given in the series array. Configuration options for the series are given in three levels. Options for all series in a chart are given in the plotOptions['series'] dict. Then options for all series of a specific type are given in the plotOptions of that type, for example plotOptions[line]. Next, options for one single series are given in the specific series array:
python
'plotOptions': {
    'enabled': Boolean,
    'align': String,
    'backgroundColor': String,
    ...
}
title and subtitle dicts (complete api for title and for subtitle): this options controls the appeareance of the title and subtitle of the chart. The keys are almost similar for both options:
python
'title': {
    'align': String,
    'text': String,
    ...
}
tooltip dict (complete api): Options for the tooltip that appears when the user hovers over a series or point:
python
'tooltip': {
    'enabled': Boolean,
    'backgroundColor': 'a_valid_html_color',
    'borderColor': 'a_valid_html_color',
    ...
}
xAxis and yAxis dicts (complete api for xAxis and for yAxis): The x axis or category axis and the y axis or the value axis. Normally, xAxis is the horizontal axis and yAxis the vertical axis except if the chart is inverted. The keys are pretty similar for both options:
python
'xAxis': {
    'min': float or int,
    'max': float or int,
    'title': {a dict with options},
    'lineColor': 'A_valid_html_color',
    ...
}
series dict (complete api): The actual series to append to the chart. In addition to the possible options, any member of the plotOptions for that specific type of plot can be added to a series individually. For example, even though a general lineWidth is specified in plotOptions['series'], an individual lineWidth can be specified for each series:
data list: It is a list that can be one of the following options (we will come back to this later):
An array of numerical values. In this case, the numerical values will be interpreted as y values, and x values will be automatically calculated, either starting at 0 and incrementing by 1, or from pointStart and pointInterval given in the plotOptions dict. If the axis has categories, these will be used. This option is not available for range series. 
An array of arrays with two values. In this case, the first value is the x value and the second is the y value. If the first value is a string, it is applied as the name of the point, and the x value is incremented following the above rules. For range series, the arrays will be interpreted as [x, low, high]. In this cases, the x value can be skipped altogether to make use of pointStart and pointRange.
An array of objects with named values. In this case the objects are point configuration objects. Range series values are given by low and high.
python
'series': {
    'data': [* see above],
    'name': String,
    'type': String,
    ...
}
Let's see a more complete (and ugly) example using several configuration options:
End of explanation
%%brython -s globaloptions
from browser import window
Highcharts = window.Highcharts
global_options = {
    'colors': ['rgb(0, 107, 164)', 'rgb(255, 128, 114)',
               'rgb(171, 171, 171)', 'rgb(89, 89, 89)',
               'rgb(95, 158, 209)', 'rgb(200, 82, 0)',
               'rgb(137, 137, 137)', 'rgb(162, 200, 236)',
               'rgb(256, 188, 121)', 'rgb(207, 207, 207)'],
    'chart':{
        'plotBackgroundColor': 'rgb(229, 229, 229)'
    },
    'credits':{
        'enabled': False
    },
    'legend':{
        'align': 'right',
        'verticalAlign': 'middle',
        'layout': 'vertical',
        'borderWidth': 0,
        'enabled': True
    },
    'plotOptions':{
        'area': {
            'fillOpacity': 0.5,
            'marker': {'enabled': False},
        },
        'arearange': {
            'fillOpacity': 0.5,
            'marker': {'enabled': False},
        },
        'areaspline': {
            'fillOpacity': 0.5,
            'marker': {'enabled': False},
        },
        'areasplinerange': {
            'fillOpacity': 0.5,
            'marker': {'enabled': False},
        },
        'bar': {
            'borderWidth': 0
        },
        'boxplot': {
            'fillColor': '#FAFAFA',
            'lineWidth': 2,
            'medianWidth': 4,
            'stemDashStyle': 'line',
            'stemWidth': 1,
            'whiskerLength': '30%',
            'whiskerWidth': 2
        },
        'column': {
            'borderWidth': 0
        },
        'columnrange': {
            'borderWidth': 0
        },
        'errorbar': {
            'color': '#fefefe',
            'lineWidth': 2
        },
        'line': {
            'marker': {'enabled': False},
            'lineWidth': 2
        },
        'scatter': {
            'marker': {
                'enabled': True,
                'lineWidth': 0,
                'symbol': 'circle',
                'radius': 5
            },
        },
        'spline': {
            'marker': {'enabled': False},
            'lineWidth': 2
        },
        'waterfall': {
            'borderWidth': 0
        }
    },
    'subtitle': {
        'align': 'center',
        'style': {
            'color': '#555555',
            'fontWeight': 'bold'
        }
    },
    'title': {
        'align': 'center',
        'text': None,
        'style': {
            'color': '#000000',
            'fontWeight': 'bold'
        }
    },
    'tooltip': {
        'backgroundColor': 'rgba(255,255,224,0.5)',
        'borderRadius': 5,
        'crosshairs': [{
                'width': 3,
                'color': '#ffffff',
                'dashStyle': 'shortdot'
            }, {
                'width': 3,
                'color': '#ffffff',
                'dashStyle': 'shortdot'
            }], 
        'hideDelay': 200,
        'enabled': True,
        'shadow': False,
        
    },
    'xAxis': {
        'gridLineColor': '#FFFFFF',
        'gridLineWidth': 1,
        'lineColor': 'rgb(229, 229, 229)',
        'tickColor': 'rgb(229, 229, 229)',
        'shadow': False,
        
    },
    'yAxis': {
        'gridLineColor': '#FFFFFF',
        'gridLineWidth': 1,
        'lineColor': 'rgb(229, 229, 229)',
        'tickColor': 'rgb(229, 229, 229)',
        'shadow': False,
        
    }
}
Highcharts.setOptions.new(global_options)
Explanation: I got it!!! It's the ugliest chart in the world!!!
Defining options for all the charts
If we want we can define some of the options to be used during a complete session so we don't have to define each of the options when defining a new chart.
We will use <code style="background-color: yellow;">Highcharts.setOptions</code> to create a set of options that could be overwritten on each individual chart if necessary. You can learn more about how to create themes for highcharts here.
In general, I don't like some default values for Highcharts and as Randall Olson has said, sometimes less is more. Also, as I have some degree of color blindness I will use the 'color blind 10' palette of colors from Tableau.
End of explanation
html = <div id="hc_ex3" style="width: 700px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart':{'renderTo': 'hc_ex3'},
    'title': {'text': 'Monthly Average Temperature'},
    'subtitle': {'text': 'Source: WorldClimate.com'},
    'xAxis': {'categories': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                             'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']},
    'yAxis': {'title': {'text': 'Temperature (°C)'}},
    'tooltip': {'valueSuffix': '°C'},
    'series': [{'name': 'Tokyo',
                'data': [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]}]
}
hc(config)
Explanation: And now, let's repeat our first example again after the global configuration:
End of explanation
html = 
<div style="float: left;">
  <div id="hc_ex4a" style="width: 400px; height: 300px;"></div>
  <div id="hc_ex4b" style="width: 400px; height: 300px;"></div>
</div>
<div style="float: left;">
  <div id="hc_ex4c" style="width: 400px; height: 300px;"></div>
  <div id="hc_ex4d" style="width: 400px; height: 300px;"></div>
</div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# Bar
config = {
    'chart': {'renderTo': 'hc_ex4a', 'type': 'bar'},
    'xAxis': {'categories': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                             'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']},
    'yAxis':  {'title': {'text': 'Temperature (°C)'}},
    'tooltip': {'valueSuffix': '°C'},
    'series': [{'name': 'Tokyo',
                'data': [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]}]
}
hc(config)
# Area
config = {
    'chart': {'renderTo': 'hc_ex4b', 'type': 'area'},
    'xAxis': {'categories': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                             'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']},
    'yAxis': {'title': {'text': 'Temperature (°C)'}},
    'tooltip': {'valueSuffix': '°C'},
    'series': [{'name': 'Tokyo',
                'data': [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]}]
}
hc(config)
# Bubble
config = {
    'chart': {'renderTo': 'hc_ex4c', 'type': 'scatter', 'zoomType': 'xy'},
    'title': {'text': 'You can pan and zoom'},
    'series': [{'name': 'Tokyo',
                'data': [[7.0, 6.9], [9.5, 14.5], [18.2, 21.5], [25.2, 26.5], [23.3, 18.3], [13.9, 9.6]]}]
}
hc(config)
# Pie
config = {
    'chart': {'renderTo': 'hc_ex4d', 'type': 'pie', 'plotBackgroundColor': 'white'},
    'series': [{'name': 'Python scientific libs',
                'data': [['scipy', 6.9], ['IPython', 14.5], 
                         ['Matplotlib', 21.5], ['Numpy', 26.5], ['Pandas', 18.3]]}]
}
hc(config)
Explanation: Much better than the ugly chart. 
And other simple charts will look like the following:
End of explanation
html = <div id="hc_ex5" style="width: 700px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart': {'renderTo': 'hc_ex5'},
    'yAxis':  {'title': {'text': 'Temperature (°C)'}},
    'tooltip': {'valueSuffix': '°C'},
    'series': [{'name': 'Tokyo',
                'data': [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]},
               {'name': 'Madrid',
                'data': [3.0, 5.4, 6.5, 12.7, 16.8, 21.4, 26.5, 26.2, 24.3, 17.3, 11.8, 6.7]}]
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span> In the previous figures we have included some new options in the chart dict:
<code style="background-color: yellow;">'type': 'type_of_chart'</code>. It indicates which chart will be used to render the data.
<code style="background-color: yellow;">'zoomType': 'xy'</code>. It allows us to zoom after the selection of an area with the mouse.
Also, in the Pie chart, we have used the option <code style="background-color: yellow;">'plotBackgroundColor': 'white'</code> so the global option defined before is not used.
Using data
Before, we have seen three different ways to insert data into a chart. Let's see it again to understand better how it is used:
An array of numerical values. In this case, the numerical values will be interpreted as y values, and x values will be automatically calculated, either starting at 0 and incrementing by 1, or from pointStart and pointInterval given in the plotOptions dict. If the axis has categories, these will be used. This option is not available for range series.
We have seen examples before but let's create a more complete example using this way:
End of explanation
html = <div id="hc_ex6" style="width: 700px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart': {'renderTo': 'hc_ex6', 'type': 'line'},
    'yAxis':  {'title': {'text': 'Temperature (°C)'}},
    'tooltip': {'valueSuffix': '°C'},
    'series': [{'name': 'Neverland',
                'data': [[1, 6.9], [3, 14.5], [7, 21.5], [8, 26.5], [9, 18.3], [10, 9.6]]}]
}
hc(config)
Explanation: An array of arrays with two values. In this case, the first value is the x value and the second is the y value. If the first value is a string, it is applied as the name of the point, and the x value is incremented following the above rules and the string will be used in the tooltip of the point. For range series, the arrays will be interpreted as [x, low, high]. In this cases, the x value can be skipped altogether to make use of pointStart and pointRange.
This way has been used in the scatter chart previously. In the example above we have seen that the x values start at 0. If we want a different behaviour we could define the x values as follows:
End of explanation
html = <div id="hc_ex7" style="width: 700px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart': {'renderTo': 'hc_ex7', 'type': 'line'},
    'yAxis':  {'title': {'text': 'Temperature (°C)'}},
    'tooltip': {'valueSuffix': '°C'},
    'series': [{'name': 'Neverland',
                'data': [['Jan', 6.9], ['Mar', 14.5], ['Jul', 21.5], ['Aug', 26.5], ['Sep', 18.3], ['Oct', 9.6]]}]
}
hc(config)
Explanation: If the x values are not a valid number it will be used as a label in the tooltip and the x values will start by 0 and incrementing by 1. For example:
End of explanation
from brythonmagic import load_js_lib
load_js_lib("https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/highcharts-more.js")
html = <div id="hc_ex8" style="width: 700px; height: 300px;"></div>
%%brython -h html
import random
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = [{'name': 'Data {}'.format(i+1), 
         'color': 'rgb(100,50,{0})'.format(random.randrange(0,255)), 
         'y': random.randrange(0,25), 
         'x': i+1} for i in range(10)]
config = {
    'chart': {'renderTo': 'hc_ex8'},
    'yAxis':  {'title': {'text': 'Temperature (°C)'}},
    'series': [{'data': data, 'type': 'line', 'color': 'black'},
               {'data': data, 'type': 'bubble'}]
}
hc(config)
Explanation: An array of objects with named values. In this case the objects are point configuration objects. Range series values are given by low and high.
This is the most complete case as you can define more precisely how the data is displayed.
[HINT] In the next chart we will use the 'bubble' chart type. We must load a new javascript file as the highcharts.js doesn't provide the complete functionality of Highcharts and some type of charts (like 'arearange', 'bubble',...) are included as extras. The new javascript file is highcharts-more.js.
End of explanation
html = <div id="hc_ex9" style="width: 900px; height: 300px;"></div>
%%brython -h html
import random
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = [[i+1, random.randrange(0,35)] for i in range(100)] 
config = {
    'chart': {'renderTo': 'hc_ex9', 'type': 'line', 'zoomType': 'x'},
    'yAxis':  {'title': {'text': 'Wind speed (m/s)'}},
    'series': [{'data': data}],
    'plotOptions': {
        'line': {'dataLabels': {'enabled': True}, 'enableMouseTracking': False}
    },
    'title': {'text': 'Click and drag to zoom'}
}
hc(config)
Explanation: On each data value we have used a name (shown in the tooltip), a color (used in scatter, bar, column, bubble,..., charts but not in line or area charts, for example) and the x and y values.
Types of charts
Line charts
We already have seen several line charts. Let's see something more advanced. In the following example we will include the data value for each record and we will be able to choose an area of the chart to zoom on the chosen subset.
End of explanation
html = <div id="hc_ex10" style="width: 900px; height: 300px;"></div>
%%brython -h html
import random
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = [[i+1, random.randrange(10,105)] for i in range(100)] 
config = {
    'chart': {'renderTo': 'hc_ex10'},
    'xAxis':  {'min': -20},
    'yAxis':  {
        'title': {'text': 'Mean Daily NO2 (ug/m3)'},
        'max': 110,
        'minorGridLineWidth': 0,
        'gridLineWidth': 0,
        'alternateGridColor': None,
        'plotBands': [{ 
            'from': 0,
            'to': 15,
            'color': 'rgba(100,100,255,0.5)',
            'label': {
                'text': 'Clean air',
                'style': {
                    'color': 'black'
                }
            }
        }, { 
            'from': 15,
            'to': 40,
            'color': 'rgba(0,255,0,0.5)',
            'label': {
                'text': 'Below EU limit',
                'style': {
                    'color': 'black'
                }
            }
        }, { 
            'from': 40,
            'to': 120,
            'color': 'rgba(255,0,0,0.5)',
            'label': {
                'text': 'Above EU limit',
                'style': {
                    'color': 'black'
                }
            }
        }]
    },
    'series': [{'data': data, 'lineWidth': 2, 'color': 'black'}]
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span> In the previous figure we have included some new options in the chart dict:
<code style="background-color: yellow;">'zoomType': 'x'</code>. It allows us to zoom after the selection of an area with the mouse. In this case, the zoom is over the x axis
Also, in the <code style="background-color: yellow;">plotOptions</code> dict, we have included some new options.
<code style="background-color: yellow;">'line': {'dataLabels': {'enabled': True}, 'enableMouseTracking': False}</code>. The <code style="background-color: yellow;">'dataLabels'</code> option allow us to show the value of each record while the <code style="background-color: yellow;">'enableMouseTracking'</code> option allows us to disable the default mouse interaction with the plot (tooltip,...).
In the following plot we are defining some areas in the background to help highlight some aspects of the dataset:
End of explanation
html = <div id="hc_ex11" style="width: 900px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = [[3**i, i] for i in range(1, 10)] 
config = {
    'chart': {'renderTo': 'hc_ex11', 'type': 'spline'},
    'yAxis':  {'type': 'logarithmic', 'opposite': True, 'offset': 30},
    'legend': {'align': 'left'},
    'series': [{'data': data, 'lineWidth': 4, 'color': 'black'}]
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span> In the previous figure we have included some new options in the options dict:
<code style="background-color: yellow;">'xAxis': {'min': -20}</code>. This indicates the minimum value for the x axis.
With the following code we have suppresed the grid lines for the y axis and added some band colors. I think the code is self-explanatory.
<b><pre><div style="background-color: yellow;">'yAxis':  {
    'title': {'text': 'Mean Daily NO2 (ug/m3)'},
    'max': 110,
    'minorGridLineWidth': 0,
    'gridLineWidth': 0,
    'alternateGridColor': None,
    'plotBands': [{ 
        'from': 0,
        'to': 15,
        'color': 'rgba(100,100,255,0.5)',
        'label': {
            'text': 'Clean air',
            'style': {
                'color': 'black'
            }
        }
    }, { 
        'from': 15,
        'to': 40,
        'color': 'rgba(0,255,0,0.5)',
        'label': {
            'text': 'Below EU limit',
            'style': {
                'color': 'black'
            }
        }
    }, { 
        'from': 40,
        'to': 120,
        'color': 'rgba(255,0,0,0.5)',
        'label': {
            'text': 'Above EU limit',
            'style': {
                'color': 'black'
            }
        }
    }]
}</div></pre></b> 
In the next plot we are going to play a little bit with the axis, where is the y axis located?, and the legend?:
End of explanation
html = <div id="hc_ex12container" style="height: 350px;">
  <div id="hc_ex12" style="width: 900px; height: 300px;"></div>
</div>
%%brython -h html
from browser.timer import set_interval, clear_interval
from browser import window, document, html
from random import randrange
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = [[i, randrange(0,10)] for i in range(0, 20)]
data_tmp = data[:]
config = {
    'chart': {
        'renderTo': 'hc_ex12', 
        'type': 'spline'
    },
    'series': [{'data': data, 'lineWidth': 2, 'color': 'black', 'animation': False,
                'marker': {'enabled': True}}]
}
hc(config)
### NEW CODE ###
idtimer = None
# A button to animate the plot with new data
document['hc_ex12container'] <= html.BUTTON('Animate', Id = 'anim')
def add_point():
    global data_tmp
    x = data_tmp[-1][0] + 1
    y = randrange(0,10)
    data_tmp.append([x, y])
    config['series'][0]['data'] = data_tmp[-20:]
    hc(config)
def animate(ev):
    global idtimer, config, data_tmp
    idtimer = set_interval(add_point, 1000)
document['anim'].bind('click', animate)
# A button to stop the plot with new data
document['hc_ex12container'] <= html.BUTTON('Stop', Id = 'stop')
def stop(ev):
    global idtimer
    clear_interval(idtimer)
document['stop'].bind('click', stop)
# A button to reset the plot with the original values
document['hc_ex12container'] <= html.BUTTON('Reset', Id = 'reset')
def reset(ev):
    global idtimer, config, data, data_tmp
    if idtimer:
        clear_interval(idtimer)
        data_tmp = data[:]
    config['series'][0]['data'] = data
    hc(config)
    
document['reset'].bind('click', reset)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span> In the previous figure we have included some new options to modify the y axis:
<code style="background-color: yellow;">'yAxis':  {'type': 'logarithmic', 'opposite': True, 'offset': 30}</code>. The axis scale is logarithmic, it is located on the opposite site and is located with an offset of 30px from the plot area.
We can include some interactivity to the plot using some basic controls. With the buttons you can update the plot (every second a new point is created), stop the updates or reset to the original state:
End of explanation
html = <div id="hc_ex13" style="width: 900px; height: 300px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data1 = [[i, randrange(0,10)] for i in range(0, 20)]
data2 = [[i, randrange(0,10)] for i in range(0, 20)]
config = {
    'chart': {
        'renderTo': 'hc_ex13', 
        'type': 'area'
    },
    'series': [{'data': data1, 'dashStyle': 'ShortDot', 'lineWidth': 3},
               {'data': data2}]
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span> In the previous figure we have included some Brython specific code to animate the figure:
<code style="background-color: yellow;">document['hc_ex12container'].append(html.BUTTON('xxx', Id = 'xxx'))</code>. With this code we are appending some buttons to the html div with id 'hc_ex12container', i.e., the html div element that contains the chart and the buttons. See the Brython docs for more info.
<code style="background-color: yellow;">document['xxx'].bind('click', xxx)</code>. With this code we are attaching some functionality (events) to some DOM elements. See the Brython docs for more info.
Finally, we have defined some functions to manage the events using the browser.timer module. See the Brython docs for more info.
Area charts
As some area charts are quite similar to line plots I will write some examples and I will only explain the code that is relevant:
A simple area chart:
End of explanation
html = <div id="hc_ex14" style="width: 900px; height: 300px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data1 = [[i, randrange(0,10)] for i in range(0, 20)]
data2 = [[i, randrange(0,10)] for i in range(0, 20)]
config = {
    'chart': {
        'renderTo': 'hc_ex14', 
        'type': 'area'
    },
    'series': [{'data': data1, 'lineWidth': 3},
               {'data': data2}],
    'plotOptions': {'area': {'stacking': 'normal'}},
    'tooltip': {'shared': True},
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
<code style="background-color: yellow;">'dashStyle': 'ShortDot'</code>. This option in the first data series modifies the line defining the area. In this case we have used 'ShortDot' but there are ather options.
A simple stacked area chart:
End of explanation
html = <div id="hc_ex15" style="width: 900px; height: 300px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data1 = [[i, randrange(5,10), randrange(10,15)] for i in range(0, 20)]
data2 = [[i, (lst[1] + lst[2]) / 2.] for i, lst in enumerate(data1)]
config = {
    'chart': {
        'renderTo': 'hc_ex15'
    },
    'series': [{'data': data2, 'type': 'line', 'name': 'mean', 'lineWidth': 3, 'color': 'black'},
               {'data': data1, 'lineWidth': 1, 'type': 'arearange', 'name': 'extremes'}],
    'tooltip': {'shared': True}
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
<code style="background-color: yellow;">'plotOptions': {'area': {'stacking': 'normal'}}</code>. This indicates that the areas will be stacked. We can choose a 'normal' or a 'percent' stacking. Other chart types like line, bar, columns,.., can be stacked.
<code style="background-color: yellow;">'tooltip': {'shared': True}</code>. This option indicates that the tooltip is shared between the datasets so the tooltip will show the information from all the available datasets.
A simple arearange chart combined with a line plot:
End of explanation
html = <div id="hc_ex16" style="width: 900px; height: 300px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data1 = [[i, -randrange(1,15)] for i in range(0, 20)]
data2 = [[i,  randrange(1,15)] for i in range(0, 20)]
config = {
    'chart': {
        'renderTo': 'hc_ex16',
        'type': 'bar'
    },
    'series': [{'data': data1, 'name': 'negative'},
               {'data': data2, 'name': 'positive'}],
    'plotOptions': {'bar': {'stacking': 'normal'}},
    'tooltip': {'shared': True},
    'xAxis': [{'opposite': False}, {'opposite': True, 'linkedTo': 0}]
}
hc(config)
Explanation: Column and bar charts
A bar plot with positive and negative values:
End of explanation
html = <div id="hc_ex17container">
  <div id="hc_ex17" style="position: relative; float: left; width: 700px; height: 300px; margin: 20px;"></div>
  <div id="tablediv"></div>
</div>
%%brython -h html
from browser import window, document, html
from random import randrange
Highcharts = window.Highcharts
# first we create a table with two series of data, X and Y:
tab = html.TABLE()
tab.style = {'textAlign': 'center', 'width': '50px'}
tab <= html.TR(html.TD('X') + html.TD('Y'))
for i in range(5):
    tab <= html.TR(
            html.TD(
                html.INPUT(
                    Id = 'x' + str(i), value = randrange(1,5), style = {'width': '50px'}
                )
            ) + 
            html.TD(
                html.INPUT(
                    Id = 'y' + str(i), value = randrange(1,5), style = {'width': '50px'}
                )
            )
        )
    
document['tablediv'] <= tab
# Function to retrieve the data from the table
def get_data():
    data1 = []
    data2 = []
    for i in range(5):
        print('x' + str(i))
        data1.append(float(document['x' + str(i)].value))
        data2.append(float(document['y' + str(i)].value))
    return [data1, data2]
# Function to update the chart
def update(ev):
    global config, hc
    datasets = get_data()
    config['series'][0]['data'] = datasets[0]
    config['series'][1]['data'] = datasets[1]
    hc(config)
    print(datasets)
# Button and event
document['hc_ex17container'] <= html.BUTTON('Update', Id = 'btn')
document['btn'].bind('click', update)
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
datasets = get_data()
data1 = datasets[0]
data2 = datasets[1]
config = {
    'chart': {
        'renderTo': 'hc_ex17',
        'type': 'column'
    },
    'series': [{'data': data1, 'name': 'X'},
               {'data': data2, 'name': 'Y'}],
    'title': {'text': 'Modify the values in the table and update'}
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
<code style="background-color: yellow;">'xAxis': [{'opposite': False}, {'opposite': True, 'linkedTo': 0}]</code>. We are defining two x axis, the second one in the opposite side of the plot area and the values are linked to the first axis, i.e., both axis are the same but each one on one side of the chart.
A bar plot with interactive values:
End of explanation
html = <div id="hc_ex18" style="width: 600px; height: 300px;"></div>
%%brython -h html
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# Pie
config = {
    'chart': {'renderTo': 'hc_ex18', 'type': 'pie'},
    'series': [{'name': 'Python scientific libs', 'innerSize': '60%',
                'data': [['scipy', 6.9], ['IPython', 14.5], 
                         ['Matplotlib', 21.5], ['Numpy', 26.5], ['Pandas', 18.3]]}]
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
In this case, there is no relevant Highcharts code and the Brython specific code is out of the scope of this tutorial but it is pretty similar to that seen previously in a previous example.
Pie charts
In the examples above we have seen a simple pie plot. A donut plot would be quite similar:
End of explanation
html = <div id="hc_ex19" style="width: 600px; height: 300px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data1 = [[i + randrange(-2, 2), randrange(i-3,i+3)] for i in range(0, 20)]
data2 = [[i + randrange(-2, 2) + 2, randrange(i-3,i+3)] for i in range(0, 20)]
# Scatter
config = {
    'chart': {'renderTo': 'hc_ex19', 'type': 'scatter'},
    'series': [{'name': 'Station 1 vs model', 'data': data1},
               {'name': 'Station 2 vs model', 'data': data2}],
    'xAxis': {'title': {'text': 'Station'}},
    'yAxis': {'title': {'text': 'Model'}}
}
hc(config)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
<code style="background-color: yellow;">'innerSize': '50%'</code>. This is the only difference wth the previous pie plot example. It indicates radius where the pie plot should start from the centre.
Scatter and bubble charts
In the examples above we have seen a simple scatter plot. A scatter plot with two datasets is similar:
End of explanation
html = <div id="hc_ex20" style="width: 600px; height: 300px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = []
for i in range(20):
    x = randrange(-10, 10)
    y = randrange(-10, 10)
    z = randrange(1, 20)
    data.append({'x': x, 'y': y, 'z': z, 
                 'color': 'rgb(40,40,{0})'.format(int(z * 255 / 20)),
                 'marker': {'lineWidth': 1, 'lineColor': 'black'}})
# Scatter
config = {
    'chart': {'renderTo': 'hc_ex20', 'type': 'bubble'},
    'series': [{'name': 'bubbles', 'data': data}]
}
hc(config)
Explanation: A bubble plot with different colors depending on the size for each record would be as follows:
End of explanation
from brythonmagic import load_js_lib
load_js_lib("https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/highcharts-3d.js")
Explanation: 3d Charts
For this examples we should first load the 3d highcharts library:
End of explanation
html = 
<div id="hc_ex21" style="width: 900px; height: 400px;"></div>
<div id="sliders">
  <table>
    <tr>
      <td>Alpha Angle</td>
      <td>
        <input id="R0" type="range" min="0" max="45" value="15"/> <span id="R0-value" class="value"></span>
      </td>
    </tr>
    <tr>
      <td>Beta Angle</td>
      <td>
        <input id="R1" type="range" min="0" max="45" value="15"/> <span id="R1-value" class="value"></span>
      </td>
    </tr>
  </table>
</div>
%%brython -h html
from browser import window, document
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
config = {
    'chart': {
        'renderTo': 'hc_ex21',
        'plotBackgroundColor': 'white',
        'type': 'column',
        'margin': 100,
        'options3d': {
            'enabled': True,
            'alpha': 15,
            'beta': 15,
            'depth': 50,
            'viewDistance': 50
        }
    },
    'plotOptions': {'column': {'depth': 25}},
    'series': [{'data': [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 
                         135.6, 148.5, 216.4, 194.1, 95.6, 54.4]}],
    'xAxis': {'gridLineColor': '#C0C0C0'},
    'yAxis': {'gridLineColor': '#C0C0C0'}
}
columns = hc(config)
def show_values():
    document['R0-value'].html = columns.options.chart.options3d.alpha
    document['R1-value'].html = columns.options.chart.options3d.beta
show_values()
# activate the sliders
def change_alpha(ev):
    columns.options.chart.options3d.alpha = ev.target.value
    show_values()
    columns.redraw(False)
def change_beta(ev):
    columns.options.chart.options3d.beta = ev.target.value
    show_values()
    columns.redraw(False)
document['R0'].bind('change', change_alpha)
document['R1'].bind('change', change_beta)
Explanation: With the 3d 'module' loaded we can see a new example where some interactivity is added:
End of explanation
from brythonmagic import load_js_lib
load_js_lib("https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/modules/heatmap.js")
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
<code style="background-color: yellow;">'options3d': {'enabled': True,'alpha': 15,'beta': 15,'depth': 50,'viewDistance': 50}'</code>. In this case, we are switching on the 3d options and the initial view of the plot.
You can create 3D pie, donut, scatter,..., plots.
Heat map
In this case, as we did it before, we have to add a new module called heatmap:
End of explanation
html = <div id="hc_ex22" style="width: 900px; height: 400px;"></div>
%%brython -h html
from random import randrange
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
# First we create the data to be passed to the plot
data = []
for y in range(7):
    for x in range(7):
        data.append([y, x, randrange(0,150)])
    
config = {
    'chart': {
        'renderTo': 'hc_ex22',
        'type': 'heatmap',
        'marginTop': 40,
        'marginBottom': 40
    },
    'title': {'text': 'Commits made last week :-P'},
    'xAxis': {'categories': ['Numpy', 'Scipy', 'Matplotlib', 'IPython', 
                             'Pandas', 'Brython', 'Brythonmagic']},
    'yAxis': {'categories': ['Monday', 'Tuesday', 'Wednesday', 
                             'Thursday', 'Friday', 'Saturday', 'Sunday'],
              'title': {'text': None}},
    'colorAxis': {'min': 0,
                  'minColor': '#FFFFFF',
                  'maxColor': JSConstructor(Highcharts.getOptions)().colors[0]},
    'legend': {
        'align': 'right',
        'layout': 'vertical',
        'margin': 0,
        'verticalAlign': 'top',
        'y': 25,
        'symbolHeight': 300
    },
    'series': [{
        'borderWidth': 1,
        'data': data,
        'dataLabels': {
            'enabled': True,
            'color': 'black',
            'style': {
                    'textShadow': 'none',
                    'HcTextStroke': None
            }
        }
    }]
}
hc(config)
Explanation: A simple heatmap would be as follows:
End of explanation
%%brython -s wrapper01
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
class HC:
    def __init__(self, container):
        self.options = {}
        self.options['chart'] = {}
        self.options['chart']['renderTo'] = container
        self.options['title'] = {}
        self.options['title']['text'] = ""
        self.options['legend'] = {}
        self.options['legend']['enabled'] = False
        self.options['subtitle'] = {}
        self.options['subtitle']['text'] = ""
        self.options['series'] = []
  
    def show(self):
        hc(self.options)
html = <div id="hc_ex23" style="width: 900px; height: 400px;"></div>
%%brython -h html -S wrapper01
plt = HC('hc_ex23')
plt.show()
print(plt.options)
Explanation: <span style="background-color: #90EE90">[NEW CODE]</span>
<code style="background-color: yellow;">'colorAxis': {'min': 0, 'minColor': '#FFFFFF', 'maxColor': JSConstructor(Highcharts.getOptions)().colors[0]},</code>. The colorAxis adds a colorbar to the plot.
Other chart types
We already have seen line, bubble, column, bar, donut, scatter, ..., charts. You can create Pyramid, Funnel, Waterfall or others.
Let's use Highcharts in a more pythonic way
All we have seen until now is better that writting plain javascript but the use of Highcharts is not very Pythonic.
Creating a simple wrapper for Highcharts:
Let's start with something very simple
End of explanation
%%brython -s wrapper02
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
class HC:
    def __init__(self, container):
        self.options = {}
        self.options['chart'] = {}
        self.options['chart']['renderTo'] = container
        self.options['title'] = {}
        self.options['title']['text'] = ""
        self.options['legend'] = {}
        self.options['legend']['enabled'] = False
        self.options['subtitle'] = {}
        self.options['subtitle']['text'] = ""
        self.options['series'] = []
        
    def show(self):
        hc(self.options)
    
    def title(self, text):
        self.options['title']['text'] = text
        #self.show()
    
    def subtitle(self, text):
        self.options['subtitle']['text'] = text
        #self.show()
html = <div id="hc_ex24" style="width: 900px; height: 400px;"></div>
%%brython -h html -S wrapper02
plt = HC('hc_ex24')
plt.title('Dummy title')
plt.subtitle('Dummy title')
plt.show()
Explanation: Ok, not very exciting. We initialise with an empty dictionary of options and with the show method we pass the options dictionary to Highcharts and we can plot an empty chart. As stated before, not very fascinating. Let's add options to include a title and a subtitle.
[HINT] The -s option in brythonmagic is used to name a brython cell ('wrapper01' is the name for the portion of code defined in the first cell of this section). With the name of that cell the code of the cell can be used in a new Brython cell using the -S option. The use of the -S option would be like an import of the code of the cell with the defined name ('wrapper01' in this case).
End of explanation
%%brython -s wrapper03
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
class HC:
    def __init__(self, container):
        self.options = {}
        self.options['chart'] = {}
        self.options['chart']['renderTo'] = container
        self.options['title'] = {}
        self.options['title']['text'] = ""
        self.options['legend'] = {}
        self.options['legend']['enabled'] = False
        self.options['subtitle'] = {}
        self.options['subtitle']['text'] = ""
        self.options['series'] = []
        
    def show(self):
        hc(self.options)
    
    def title(self, text):
        self.options['title']['text'] = text
        #self.draw()
    
    def subtitle(self, text):
        self.options['subtitle']['text'] = text
        #self.draw()
        
    def plot(self, x, y = None, label = None, color = None, linewidth = None):
        if y:
            data = [[i, j] for i, j in zip(x, y)]
        else:
            data = x
        serie = {'data': data, 'type': 'line'}
        if linewidth:
            serie['lineWidth'] = linewidth
        if label:
            serie['name'] = label
        if color:
            serie['color'] = color
        self.options['series'].append(serie)
        #self.draw()
html = <div id="hc_ex25" style="width: 900px; height: 400px;"></div>
%%brython -h html -S wrapper03
plt = HC('hc_ex25')
plt.plot([1,2,4,5], [3,6,4,7], label = 'lineplot1', linewidth = 5, color = 'red')
plt.plot([1,2,4,5], [8,5,9,2], label = 'lineplot2', linewidth = 2, color = 'blue')
plt.title('Some line plots')
plt.show()
Explanation: Still not very funny. If you see the two new methods added, title and subtitle, there is one line commented. We can uncomment these lines if we don't want to call the show method but everytime we use a method the chart will be plotted. I didn't see any overhead doing this but let's avoid it for the moment.
Ok, let's do something more interesting plotting some data in a line chart.
End of explanation
%%brython -s wrapper04
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
class HC:
    def __init__(self, container):
        self.options = {}
        self.options['chart'] = {}
        self.options['chart']['renderTo'] = container
        self.options['title'] = {}
        self.options['title']['text'] = ""
        self.options['legend'] = {}
        self.options['legend']['enabled'] = False
        self.options['subtitle'] = {}
        self.options['subtitle']['text'] = ""
        self.options['series'] = []
        
    def show(self):
        hc(self.options)
    
    def title(self, text):
        self.options['title']['text'] = text
        #self.draw()
    
    def subtitle(self, text):
        self.options['subtitle']['text'] = text
        #self.draw()
        
    def plot(self, x, y = None, label = None, color = None, linewidth = None):
        if y:
            data = [[i, j] for i, j in zip(x, y)]
        else:
            data = x
        serie = {'data': data, 'type': 'line'}
        if linewidth:
            serie['lineWidth'] = linewidth
        if label:
            serie['name'] = label
        if color:
            serie['color'] = color
        self.options['series'].append(serie)
        #self.draw()
    
    def legend(self, loc = 'right'):
        self.options['legend']['enabled'] = True
        if loc:
            self.options['legend']['align'] = loc
        #self.draw()
html = <div id="hc_ex26" style="width: 900px; height: 400px;"></div>
%%brython -h html -S wrapper04
plt = HC('hc_ex26')
plt.title('Line plots')
plt.plot([1,2,4,5], [3,6,4,7], label = 'lineplot1', linewidth = 5, color = 'red')
plt.plot([1,2,4,5], [8,5,9,2], label = 'lineplot2', linewidth = 2, color = 'blue')
plt.legend(loc = 'left')
plt.show()
Explanation: Wow!!, with less than 40 lines of Brython code we have a wrapper to do very simple interactive charts using Highcharts in a pythonic way. We added the label keyword in the plot method. In Matplotlib, the label is used by the legend in the case we want to add a legend. Let's add a legend method to provide the label keyword some utility.
End of explanation
%%brython -s wrapper05
from browser import window
Highcharts = window.Highcharts
hc = Highcharts.Chart.new
class HC:
    def __init__(self, container):
        self.options = {}
        self.options['chart'] = {}
        self.options['chart']['renderTo'] = container
        self.options['title'] = {}
        self.options['title']['text'] = ""
        self.options['legend'] = {}
        self.options['legend']['enabled'] = False
        self.options['subtitle'] = {}
        self.options['subtitle']['text'] = ""
        self.options['series'] = []
        
    def show(self):
        hc(self.options)
    
    def title(self, text):
        self.options['title']['text'] = text
        #self.draw()
    
    def subtitle(self, text):
        self.options['subtitle']['text'] = text
        #self.draw()
        
    def plot(self, x, y = None, label = None, color = None, linewidth = None):
        if y:
            data = [[i, j] for i, j in zip(x, y)]
        else:
            data = x
        serie = {'data': data, 'type': 'line'}
        if linewidth:
            serie['lineWidth'] = linewidth
        if label:
            serie['name'] = label
        if color:
            serie['color'] = color
        self.options['series'].append(serie)
        #self.draw()
    
    def legend(self, loc = 'right'):
        self.options['legend']['enabled'] = True
        if loc:
            self.options['legend']['align'] = loc
        #self.draw()
    
    def scatter(self, x, y, label = None, color = None):
        data = [[i, j] for i, j in zip(x, y)]
        serie = {'data': data, 'type': 'scatter'}
        if label:
            serie['name'] = label
        if color:
            serie['color'] = color
        self.options['series'].append(serie)
        #self.draw()
html = <div id="hc_ex27" style="width: 900px; height: 400px;"></div>
%%brython -h html -S wrapper05
plt = HC('hc_ex27')
plt.title('Line plots')
plt.plot([1,2,4,5], [3,6,4,7], label = 'lineplot1', linewidth = 5, color = 'red')
plt.plot([1,2,4,5], [8,5,9,2], label = 'lineplot2', linewidth = 2, color = 'blue')
plt.scatter([1,2,4,5], [2,4,6,8], label = 'scatter1', color = 'green')
plt.legend(loc = 'left')
plt.show()
Explanation: The behaviour is not similar to that in the pyplot module of the matplotlib library but we can get some basic functionality. We can add a scatter method to combine line plots with scatter plots.
End of explanation
<END_TASK>