9. Interactive Data Visualization

Damian Trilling and Penny Sheets

This notebook gives some examples for how to create interactive visualizations for the web.

We will use the following three visualization packages:

  • bokeh

  • pygal

  • plotly

bokeh allows you to create interactive visualizations in which users can hover over elements, zoom in, etc. pygal allows you to create standard charts with hover-effects. plotly is a very extensive package that is related to a whole ecosystem to build interactive apps, but since short time, you can make use of some of its functionality directly via pandas!

Download the sample data

The first time you run this notebook, you will need to download some example data. You only need to do this once, and should “comment out” (put hashtags in front of) the following two lines again after running them once.

# import bokeh
# bokeh.sampledata.download()
#pip install cairosvg
# pip install bokeh
# pip install pygal
# pip install plotly

Interactivity

As discussed in the literature of week 4, interactivity should have a function. For instance, it can be used to reduce information overload while still providing information ‘on demand’ if users want to dig into it.

Consider the example below (under the bokeh section), where the user at a first glance can get an idea of the geographical distribution of unemployment, but if they really want to know more, can even get the exact number for each and every county by hovering over it.

More complicated online demos of bokeh apps are available here:

  • https://demo.bokeh.org/movies

  • https://demo.bokeh.org/weather

But first, we’ll start with an example using pygal

For more info and examples, see http://www.pygal.org .

It will make your bar charts etc. just a bit more attractive by allowing things like displaying values when hovering over columns with the mouse.

import pygal
import bokeh
import pandas as pd
%matplotlib inline
# First we create a bar graph object (this is sort of like how we did in Seaborn, creating a blank canvas 
# before telling it what to put on that canvas.)

mylittle_bar_chart = pygal.Bar()                                            

# Next we add some values to it; in this case, we're adding the Fibonacci number sequence, and labeling it accordingly.
mylittle_bar_chart.add('Fibonacci', [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
mylittle_bar_chart.add('whatever', [3,5,6,7,8])
../_images/09-interactive_visualizations_9_0.svg
print("Penny INC went up tremenously", 
      mylittle_bar_chart.render_sparktext(),
      "and you should invest in it.")
Penny INC went up tremenously ▁▁▁▁▁▁▂▂▃▅█ and you should invest in it.
mylittle_bar_chart.render_sparkline()
b'<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="chart-f8e71380-04b9-406d-b23f-98cdd81d69ec" class="pygal-chart pygal-sparkline" viewBox="0 0 200 50" width="200" height="50"><!--Generated with pygal 2.4.0 (lxml) \xc2\xa9Kozea 2012-2016 on 2020-12-01--><!--http://pygal.org--><!--http://github.com/Kozea/pygal--><defs><style type="text/css">#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px}\n#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec{background-color:rgba(249,249,249,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec path,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec rect,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .graph{fill:rgba(0,0,0,.87)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec text.no_data{fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .title{fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .legends .legend text{fill:rgba(0,0,0,.87)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .line{stroke:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis text.major{fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y .guides:hover .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .line-graph .axis.x .guides:hover .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .stackedline-graph .axis.x .guides:hover .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .ci{stroke:rgba(0,0,0,.87)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .reactive.active,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .ci .reactive.active{stroke-width:1.5}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .series text{fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip .label{fill:rgba(0,0,0,.87)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip .label{fill:rgba(0,0,0,.87)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip .value{font-size:1.5em}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .bound{font-size:.5em}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .color-0,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .color-1,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .text-overlay .color-0 text{fill:black}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .text-overlay .color-1 text{fill:black}\n#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec text.no_data{text-anchor:middle}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .guide.line{fill:none}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .centered{text-anchor:middle}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .title{text-anchor:middle}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .legends .legend text{fill-opacity:1}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.x text{text-anchor:middle}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.x:not(.web) text[transform]{text-anchor:start}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y text{text-anchor:end}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y text[transform].backwards{text-anchor:start}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y2 text{text-anchor:start}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y2 text[transform].backwards{text-anchor:end}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .guide.line{stroke-dasharray:4,4}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .major.guide.line{stroke-dasharray:6,6}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .horizontal .axis.y .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .horizontal .axis.y2 .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .vertical .axis.x .guide.line{opacity:0}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .horizontal .axis.always_show .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y .guides:hover .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.y2 .guides:hover .guide.line,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis.x .guides:hover .guide.line{opacity:1}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .axis .guides:hover text{opacity:1}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .nofill{fill:none}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .subtle-fill{fill-opacity:.2}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .dot{stroke-width:1px;fill-opacity:1}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .dot.active{stroke-width:5px}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .dot.negative{fill:transparent}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec text,#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec tspan{stroke:none !important}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .series text.active{opacity:1}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .tooltip text{fill-opacity:1}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .showable{visibility:hidden}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .showable.shown{visibility:visible}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-f8e71380-04b9-406d-b23f-98cdd81d69ec .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style><script type="text/javascript">window.pygal = window.pygal || {};window.pygal.config = window.pygal.config || {};window.pygal.config[\'f8e71380-04b9-406d-b23f-98cdd81d69ec\'] = {"allow_interruptions": false, "box_mode": "extremes", "classes": ["pygal-chart", "pygal-sparkline"], "css": ["file://style.css", "file://graph.css"], "defs": [], "disable_xml_declaration": false, "dots_size": 2.5, "dynamic_print_values": false, "explicit_size": true, "fill": false, "force_uri_protocol": "https", "formatter": null, "half_pie": false, "height": 50, "include_x_axis": false, "inner_radius": 0, "interpolate": null, "interpolation_parameters": {}, "interpolation_precision": 250, "inverse_y_axis": false, "js": [], "legend_at_bottom": false, "legend_at_bottom_columns": null, "legend_box_size": 12, "logarithmic": false, "margin": 5, "margin_bottom": null, "margin_left": null, "margin_right": null, "margin_top": null, "max_scale": 2, "min_scale": 1, "missing_value_fill_truncation": "x", "no_data_text": "", "no_prefix": false, "order_min": null, "pretty_print": false, "print_labels": false, "print_values": false, "print_values_position": "center", "print_zeroes": true, "range": null, "rounded_bars": null, "secondary_range": null, "show_dots": false, "show_legend": false, "show_minor_x_labels": true, "show_minor_y_labels": true, "show_only_major_dots": false, "show_x_guides": false, "show_x_labels": false, "show_y_guides": true, "show_y_labels": false, "spacing": 0, "stack_from_top": false, "strict": false, "stroke": true, "stroke_style": null, "style": {"background": "rgba(249, 249, 249, 1)", "ci_colors": [], "colors": ["#F44336", "#3F51B5", "#009688", "#FFC107", "#FF5722", "#9C27B0", "#03A9F4", "#8BC34A", "#FF9800", "#E91E63", "#2196F3", "#4CAF50", "#FFEB3B", "#673AB7", "#00BCD4", "#CDDC39", "#9E9E9E", "#607D8B"], "font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "foreground": "rgba(0, 0, 0, .87)", "foreground_strong": "rgba(0, 0, 0, 1)", "foreground_subtle": "rgba(0, 0, 0, .54)", "guide_stroke_dasharray": "4,4", "label_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "label_font_size": 10, "legend_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "legend_font_size": 14, "major_guide_stroke_dasharray": "6,6", "major_label_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "major_label_font_size": 10, "no_data_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "no_data_font_size": 64, "opacity": ".7", "opacity_hover": ".8", "plot_background": "rgba(255, 255, 255, 1)", "stroke_opacity": ".8", "stroke_opacity_hover": ".9", "title_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "title_font_size": 16, "tooltip_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "tooltip_font_size": 14, "transition": "150ms", "value_background": "rgba(229, 229, 229, 1)", "value_colors": [], "value_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "value_font_size": 16, "value_label_font_family": "Consolas, \\"Liberation Mono\\", Menlo, Courier, monospace", "value_label_font_size": 10}, "title": null, "tooltip_border_radius": 0, "tooltip_fancy_mode": true, "truncate_label": null, "truncate_legend": null, "width": 200, "x_label_rotation": 0, "x_labels": null, "x_labels_major": null, "x_labels_major_count": null, "x_labels_major_every": null, "x_title": null, "xrange": null, "y_label_rotation": 0, "y_labels": null, "y_labels_major": null, "y_labels_major_count": null, "y_labels_major_every": null, "y_title": null, "zero": 0, "legends": ["Fibonacci", "whatever"]}</script></defs><title>Pygal</title><g class="graph bar-graph vertical"><rect x="0" y="0" width="200" height="50" class="background"/><g transform="translate(5, 5)" class="plot"><rect x="0" y="0" width="190" height="40" class="background"/><g class="series serie-0 color-0"><g class="bars"><g class="bar"><rect x="5.0888111888111895" y="39.23076923076923" rx="0" ry="0" width="6.43076923076923" height="0.0" class="rect reactive tooltip-trigger"/><desc class="value">0</desc><desc class="x centered">8.304195804195805</desc><desc class="y centered">39.23076923076923</desc></g><g class="bar"><rect x="21.6972027972028" y="38.53146853146853" rx="0" ry="0" width="6.43076923076923" height="0.6993006993007" class="rect reactive tooltip-trigger"/><desc class="value">1</desc><desc class="x centered">24.912587412587413</desc><desc class="y centered">38.88111888111888</desc></g><g class="bar"><rect x="38.3055944055944" y="38.53146853146853" rx="0" ry="0" width="6.43076923076923" height="0.6993006993007" class="rect reactive tooltip-trigger"/><desc class="value">1</desc><desc class="x centered">41.52097902097901</desc><desc class="y centered">38.88111888111888</desc></g><g class="bar"><rect x="54.913986013986005" y="37.83216783216783" rx="0" ry="0" width="6.43076923076923" height="1.3986013986014" class="rect reactive tooltip-trigger"/><desc class="value">2</desc><desc class="x centered">58.12937062937062</desc><desc class="y centered">38.53146853146853</desc></g><g class="bar"><rect x="71.52237762237762" y="37.13286713286713" rx="0" ry="0" width="6.43076923076923" height="2.0979020979021" class="rect reactive tooltip-trigger"/><desc class="value">3</desc><desc class="x centered">74.73776223776224</desc><desc class="y centered">38.18181818181819</desc></g><g class="bar"><rect x="88.13076923076923" y="35.73426573426573" rx="0" ry="0" width="6.43076923076923" height="3.4965034965035002" class="rect reactive tooltip-trigger"/><desc class="value">5</desc><desc class="x centered">91.34615384615385</desc><desc class="y centered">37.48251748251748</desc></g><g class="bar"><rect x="104.73916083916083" y="33.63636363636364" rx="0" ry="0" width="6.43076923076923" height="5.594405594405593" class="rect reactive tooltip-trigger"/><desc class="value">8</desc><desc class="x centered">107.95454545454545</desc><desc class="y centered">36.43356643356644</desc></g><g class="bar"><rect x="121.34755244755243" y="30.13986013986014" rx="0" ry="0" width="6.43076923076923" height="9.090909090909093" class="rect reactive tooltip-trigger"/><desc class="value">13</desc><desc class="x centered">124.56293706293705</desc><desc class="y centered">34.68531468531469</desc></g><g class="bar"><rect x="137.95594405594406" y="24.545454545454547" rx="0" ry="0" width="6.43076923076923" height="14.685314685314687" class="rect reactive tooltip-trigger"/><desc class="value">21</desc><desc class="x centered">141.17132867132867</desc><desc class="y centered">31.88811188811189</desc></g><g class="bar"><rect x="154.56433566433566" y="15.454545454545457" rx="0" ry="0" width="6.43076923076923" height="23.776223776223777" class="rect reactive tooltip-trigger"/><desc class="value">34</desc><desc class="x centered">157.77972027972027</desc><desc class="y centered">27.342657342657347</desc></g><g class="bar"><rect x="171.17272727272726" y="0.7692307692307736" rx="0" ry="0" width="6.43076923076923" height="38.46153846153846" class="rect reactive tooltip-trigger"/><desc class="value">55</desc><desc class="x centered">174.38811188811187</desc><desc class="y centered">20.000000000000004</desc></g></g></g><g class="series serie-1 color-1"><g class="bars"><g class="bar"><rect x="12.396503496503495" y="37.13286713286713" rx="0" ry="0" width="6.43076923076923" height="2.0979020979021" class="rect reactive tooltip-trigger"/><desc class="value">3</desc><desc class="x centered">15.61188811188811</desc><desc class="y centered">38.18181818181819</desc></g><g class="bar"><rect x="29.004895104895105" y="35.73426573426573" rx="0" ry="0" width="6.43076923076923" height="3.4965034965035002" class="rect reactive tooltip-trigger"/><desc class="value">5</desc><desc class="x centered">32.22027972027972</desc><desc class="y centered">37.48251748251748</desc></g><g class="bar"><rect x="45.613286713286705" y="35.03496503496503" rx="0" ry="0" width="6.43076923076923" height="4.1958041958042" class="rect reactive tooltip-trigger"/><desc class="value">6</desc><desc class="x centered">48.82867132867132</desc><desc class="y centered">37.13286713286713</desc></g><g class="bar"><rect x="62.22167832167831" y="34.33566433566433" rx="0" ry="0" width="6.43076923076923" height="4.8951048951049" class="rect reactive tooltip-trigger"/><desc class="value">7</desc><desc class="x centered">65.43706293706293</desc><desc class="y centered">36.78321678321679</desc></g><g class="bar"><rect x="78.83006993006993" y="33.63636363636364" rx="0" ry="0" width="6.43076923076923" height="5.594405594405593" class="rect reactive tooltip-trigger"/><desc class="value">8</desc><desc class="x centered">82.04545454545455</desc><desc class="y centered">36.43356643356644</desc></g></g></g></g><g class="titles"/><g transform="translate(5, 5)" class="plot overlay"><g class="series serie-0 color-0"/><g class="series serie-1 color-1"/></g><g transform="translate(5, 5)" class="plot text-overlay"><g class="series serie-0 color-0"/><g class="series serie-1 color-1"/></g><g transform="translate(5, 5)" class="plot tooltip-overlay"><g transform="translate(0 0)" style="opacity: 0" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box"/><g class="text"/></g></g></g></svg>'
# With pygal, you can render this into an .svg visualization for display in your web browser.

mylittle_bar_chart.render_in_browser()

# or you can save to a file for later embedding/placement wherever you want it:
# bar_chart.render_to_file('bar_chart.svg') 
file:///tmp/tmpdlqv9cy5.html
mylittle_bar_chart.render_to_file('mytest.svg')

Let’s do this with our own data that we used in an earlier notebook. We first do it the old-fashioned way that we already know, then we use pygal instead.

mediause = pd.read_csv('https://raw.githubusercontent.com/uvacw/datajournalism/master/mediause.csv')
mediause
gender age education radio newspaper tv internet
0 1 71 4.0 5 6 5 0
1 1 40 2.0 6 0 0 0
2 1 41 2.0 4 3 7 3
3 0 65 5.0 0 0 5 0
4 0 39 2.0 0 1 7 7
... ... ... ... ... ... ... ...
2076 0 49 5.0 3 6 6 0
2077 0 51 4.0 7 7 5 5
2078 1 31 6.0 3 5 5 6
2079 0 58 6.0 3 3 1 0
2080 1 21 3.0 2 6 6 4

2081 rows × 7 columns

frequency_of_internet_use = mediause['internet'].value_counts().sort_index()
frequency_of_internet_use
0    811
1    189
2    174
3    150
4    104
5    145
6     98
7    410
Name: internet, dtype: int64
frequency_of_internet_use.plot(kind='bar')
<AxesSubplot:>
../_images/09-interactive_visualizations_18_1.png
bar_chart = pygal.Bar()                                            

frequency_of_internet_use = mediause['internet'].value_counts().sort_index()
frequency_of_tv_use = mediause['tv'].value_counts().sort_index()
frequency_of_newspaper_use = mediause['newspaper'].value_counts().sort_index()

# let's add labels to the x axis
# we could do:
# bar_chart.x_labels = range(8) to generate the numbers 0...8
# or supply a list manually,
# or we re-use the index of our data:
bar_chart.x_labels = frequency_of_internet_use.index


# Next we add some values to it; in this case, we're adding the Fibonacci number sequence, and labeling it accordingly.
bar_chart.add('internet', frequency_of_internet_use)
bar_chart.add('tv', frequency_of_tv_use)
bar_chart.add('newspaper', frequency_of_newspaper_use)
../_images/09-interactive_visualizations_19_0.svg
bar_chart.render_to_file
<bound method PublicApi.render_to_file of <pygal.graph.bar.Bar object at 0x7efebe8119d0>>

An example with bokeh

This one is taken from an existing demo online (on the website of bokeh), to show bokeh’s capacities. But all documentation and further info can be found at the link here, for more info & examples: https://bokeh.org/

from bokeh.io import show, output_file
from bokeh.models import LogColorMapper
from bokeh.palettes import Viridis6 as palette
from bokeh.plotting import figure

from bokeh.sampledata.us_counties import data as counties
from bokeh.sampledata.unemployment import data as unemployment
len(unemployment)
3218
unemployment
{(1, 1): 9.7,
 (1, 3): 9.1,
 (1, 5): 13.4,
 (1, 7): 12.1,
 (1, 9): 9.9,
 (1, 11): 16.4,
 (1, 13): 16.7,
 (1, 15): 10.8,
 (1, 17): 18.6,
 (1, 19): 11.8,
 (1, 21): 9.9,
 (1, 23): 12.7,
 (1, 25): 17.0,
 (1, 27): 15.9,
 (1, 29): 10.4,
 (1, 31): 8.5,
 (1, 33): 11.4,
 (1, 35): 19.5,
 (1, 37): 14.0,
 (1, 39): 10.1,
 (1, 41): 9.7,
 (1, 43): 9.6,
 (1, 45): 9.3,
 (1, 47): 21.1,
 (1, 49): 14.3,
 (1, 51): 9.0,
 (1, 53): 12.9,
 (1, 55): 10.7,
 (1, 57): 12.8,
 (1, 59): 12.3,
 (1, 61): 10.0,
 (1, 63): 14.7,
 (1, 65): 12.7,
 (1, 67): 9.9,
 (1, 69): 8.9,
 (1, 71): 11.8,
 (1, 73): 10.7,
 (1, 75): 14.8,
 (1, 77): 10.5,
 (1, 79): 13.6,
 (1, 81): 8.6,
 (1, 83): 9.3,
 (1, 85): 18.5,
 (1, 87): 11.4,
 (1, 89): 7.5,
 (1, 91): 14.8,
 (1, 93): 15.2,
 (1, 95): 9.2,
 (1, 97): 11.1,
 (1, 99): 18.7,
 (1, 101): 10.2,
 (1, 103): 10.4,
 (1, 105): 19.8,
 (1, 107): 13.0,
 (1, 109): 8.7,
 (1, 111): 15.1,
 (1, 113): 12.6,
 (1, 115): 10.7,
 (1, 117): 7.6,
 (1, 119): 13.9,
 (1, 121): 13.6,
 (1, 123): 13.7,
 (1, 125): 9.0,
 (1, 127): 11.9,
 (1, 129): 15.1,
 (1, 131): 25.6,
 (1, 133): 17.5,
 (2, 13): 10.1,
 (2, 16): 8.4,
 (2, 20): 7.0,
 (2, 50): 14.8,
 (2, 60): 3.6,
 (2, 68): 3.4,
 (2, 70): 8.4,
 (2, 90): 6.9,
 (2, 100): 6.2,
 (2, 110): 5.7,
 (2, 122): 9.7,
 (2, 130): 6.1,
 (2, 150): 6.6,
 (2, 164): 5.9,
 (2, 170): 8.8,
 (2, 180): 12.1,
 (2, 185): 5.7,
 (2, 188): 13.2,
 (2, 201): 13.6,
 (2, 220): 5.9,
 (2, 232): 7.3,
 (2, 240): 8.1,
 (2, 261): 6.4,
 (2, 270): 20.4,
 (2, 280): 9.8,
 (2, 282): 6.3,
 (2, 290): 13.6,
 (4, 1): 14.8,
 (4, 3): 7.4,
 (4, 5): 7.7,
 (4, 7): 10.9,
 (4, 9): 14.4,
 (4, 11): 21.5,
 (4, 12): 8.9,
 (4, 13): 8.5,
 (4, 15): 10.2,
 (4, 17): 14.2,
 (4, 19): 8.4,
 (4, 21): 11.8,
 (4, 23): 17.2,
 (4, 25): 9.5,
 (4, 27): 24.2,
 (5, 1): 14.3,
 (5, 3): 9.1,
 (5, 5): 8.2,
 (5, 7): 5.3,
 (5, 9): 6.4,
 (5, 11): 7.8,
 (5, 13): 6.2,
 (5, 15): 4.3,
 (5, 17): 9.6,
 (5, 19): 6.3,
 (5, 21): 10.4,
 (5, 23): 5.9,
 (5, 25): 6.0,
 (5, 27): 8.1,
 (5, 29): 6.5,
 (5, 31): 5.9,
 (5, 33): 6.6,
 (5, 35): 9.9,
 (5, 37): 7.1,
 (5, 39): 7.6,
 (5, 41): 9.9,
 (5, 43): 9.1,
 (5, 45): 6.0,
 (5, 47): 5.9,
 (5, 49): 6.1,
 (5, 51): 6.6,
 (5, 53): 5.7,
 (5, 55): 8.2,
 (5, 57): 8.6,
 (5, 59): 7.3,
 (5, 61): 7.2,
 (5, 63): 7.8,
 (5, 65): 7.7,
 (5, 67): 9.2,
 (5, 69): 9.2,
 (5, 71): 6.1,
 (5, 73): 8.6,
 (5, 75): 7.9,
 (5, 77): 8.2,
 (5, 79): 8.2,
 (5, 81): 5.6,
 (5, 83): 7.7,
 (5, 85): 5.2,
 (5, 87): 5.3,
 (5, 89): 11.2,
 (5, 91): 4.5,
 (5, 93): 11.3,
 (5, 95): 7.4,
 (5, 97): 5.8,
 (5, 99): 8.7,
 (5, 101): 6.2,
 (5, 103): 7.1,
 (5, 105): 5.6,
 (5, 107): 8.8,
 (5, 109): 6.3,
 (5, 111): 7.5,
 (5, 113): 6.4,
 (5, 115): 6.2,
 (5, 117): 6.7,
 (5, 119): 6.0,
 (5, 121): 7.3,
 (5, 123): 9.4,
 (5, 125): 5.8,
 (5, 127): 6.3,
 (5, 129): 5.9,
 (5, 131): 6.2,
 (5, 133): 5.1,
 (5, 135): 7.8,
 (5, 137): 6.6,
 (5, 139): 9.5,
 (5, 141): 9.1,
 (5, 143): 5.0,
 (5, 145): 6.7,
 (5, 147): 9.1,
 (5, 149): 6.4,
 (6, 1): 11.3,
 (6, 3): 15.2,
 (6, 5): 12.1,
 (6, 7): 12.2,
 (6, 9): 14.3,
 (6, 11): 14.5,
 (6, 13): 11.2,
 (6, 15): 11.9,
 (6, 17): 11.2,
 (6, 19): 14.1,
 (6, 21): 13.8,
 (6, 23): 10.3,
 (6, 25): 30.1,
 (6, 27): 9.5,
 (6, 29): 13.9,
 (6, 31): 13.9,
 (6, 33): 14.7,
 (6, 35): 11.8,
 (6, 37): 12.7,
 (6, 39): 12.3,
 (6, 41): 8.0,
 (6, 43): 8.8,
 (6, 45): 10.1,
 (6, 47): 15.7,
 (6, 49): 11.1,
 (6, 51): 10.3,
 (6, 53): 10.0,
 (6, 55): 8.7,
 (6, 57): 10.9,
 (6, 59): 9.4,
 (6, 61): 11.3,
 (6, 63): 13.9,
 (6, 65): 14.7,
 (6, 67): 12.2,
 (6, 69): 12.5,
 (6, 71): 13.6,
 (6, 73): 10.2,
 (6, 75): 9.7,
 (6, 77): 15.5,
 (6, 79): 9.0,
 (6, 81): 9.0,
 (6, 83): 8.5,
 (6, 85): 11.8,
 (6, 87): 10.2,
 (6, 89): 14.7,
 (6, 91): 13.7,
 (6, 93): 13.5,
 (6, 95): 11.5,
 (6, 97): 9.9,
 (6, 99): 15.3,
 (6, 101): 15.1,
 (6, 103): 13.7,
 (6, 105): 15.9,
 (6, 107): 14.9,
 (6, 109): 12.7,
 (6, 111): 11.0,
 (6, 113): 10.9,
 (6, 115): 17.8,
 (8, 1): 8.1,
 (8, 3): 5.5,
 (8, 5): 6.9,
 (8, 7): 6.2,
 (8, 9): 3.4,
 (8, 11): 5.0,
 (8, 13): 5.5,
 (8, 14): 6.6,
 (8, 15): 5.1,
 (8, 17): 2.0,
 (8, 19): 7.0,
 (8, 21): 5.1,
 (8, 23): 8.4,
 (8, 25): 7.6,
 (8, 27): 5.2,
 (8, 29): 6.6,
 (8, 31): 7.7,
 (8, 33): 13.2,
 (8, 35): 5.9,
 (8, 37): 6.2,
 (8, 39): 6.0,
 (8, 41): 7.2,
 (8, 43): 7.7,
 (8, 45): 5.8,
 (8, 47): 6.0,
 (8, 49): 5.8,
 (8, 51): 4.4,
 (8, 53): 2.2,
 (8, 55): 7.2,
 (8, 57): 3.3,
 (8, 59): 6.7,
 (8, 61): 2.8,
 (8, 63): 2.9,
 (8, 65): 7.1,
 (8, 67): 4.7,
 (8, 69): 5.6,
 (8, 71): 7.0,
 (8, 73): 3.7,
 (8, 75): 4.6,
 (8, 77): 8.2,
 (8, 79): 5.3,
 (8, 81): 5.6,
 (8, 83): 6.3,
 (8, 85): 6.9,
 (8, 87): 4.9,
 (8, 89): 5.8,
 (8, 91): 4.1,
 (8, 93): 6.1,
 (8, 95): 2.6,
 (8, 97): 5.0,
 (8, 99): 5.0,
 (8, 101): 7.5,
 (8, 103): 3.9,
 (8, 105): 4.8,
 (8, 107): 6.0,
 (8, 109): 7.8,
 (8, 111): 5.3,
 (8, 113): 4.2,
 (8, 115): 3.3,
 (8, 117): 5.8,
 (8, 119): 6.7,
 (8, 121): 3.2,
 (8, 123): 7.5,
 (8, 125): 2.6,
 (9, 1): 7.8,
 (9, 3): 8.8,
 (9, 5): 7.9,
 (9, 7): 6.7,
 (9, 9): 8.9,
 (9, 11): 7.6,
 (9, 13): 6.7,
 (9, 15): 9.0,
 (10, 1): 7.9,
 (10, 3): 8.6,
 (10, 5): 7.3,
 (11, 1): 11.7,
 (12, 1): 7.1,
 (12, 3): 11.4,
 (12, 5): 8.9,
 (12, 7): 8.3,
 (12, 9): 11.1,
 (12, 11): 9.8,
 (12, 13): 8.2,
 (12, 15): 12.7,
 (12, 17): 12.1,
 (12, 19): 9.8,
 (12, 21): 13.1,
 (12, 23): 9.0,
 (12, 27): 11.7,
 (12, 29): 12.3,
 (12, 31): 11.2,
 (12, 33): 9.8,
 (12, 35): 16.2,
 (12, 37): 7.1,
 (12, 39): 9.6,
 (12, 41): 10.0,
 (12, 43): 10.0,
 (12, 45): 9.8,
 (12, 47): 11.3,
 (12, 49): 12.6,
 (12, 51): 16.8,
 (12, 53): 13.8,
 (12, 55): 11.6,
 (12, 57): 11.5,
 (12, 59): 7.2,
 (12, 61): 15.2,
 (12, 63): 7.2,
 (12, 65): 8.5,
 (12, 67): 7.2,
 (12, 69): 12.3,
 (12, 71): 13.9,
 (12, 73): 7.2,
 (12, 75): 12.1,
 (12, 77): 5.3,
 (12, 79): 11.7,
 (12, 81): 12.7,
 (12, 83): 13.3,
 (12, 85): 11.9,
 (12, 86): 11.3,
 (12, 87): 7.0,
 (12, 89): 10.7,
 (12, 91): 7.2,
 (12, 93): 13.3,
 (12, 95): 11.4,
 (12, 97): 12.8,
 (12, 99): 11.7,
 (12, 101): 12.5,
 (12, 103): 11.2,
 (12, 105): 12.7,
 (12, 107): 12.2,
 (12, 109): 9.0,
 (12, 111): 15.3,
 (12, 113): 9.4,
 (12, 115): 12.3,
 (12, 117): 10.6,
 (12, 119): 9.0,
 (12, 121): 9.8,
 (12, 123): 10.4,
 (12, 125): 8.4,
 (12, 127): 11.7,
 (12, 129): 7.2,
 (12, 131): 6.8,
 (12, 133): 9.6,
 (13, 1): 9.7,
 (13, 3): 12.6,
 (13, 5): 8.5,
 (13, 7): 9.1,
 (13, 9): 11.6,
 (13, 11): 6.7,
 (13, 13): 11.1,
 (13, 15): 13.3,
 (13, 17): 15.3,
 (13, 19): 12.4,
 (13, 21): 10.0,
 (13, 23): 9.7,
 (13, 25): 11.6,
 (13, 27): 8.7,
 (13, 29): 8.1,
 (13, 31): 9.0,
 (13, 33): 12.2,
 (13, 35): 12.7,
 (13, 37): 11.1,
 (13, 39): 9.1,
 (13, 43): 9.3,
 (13, 45): 10.8,
 (13, 47): 8.0,
 (13, 49): 10.6,
 (13, 51): 8.5,
 (13, 53): 14.6,
 (13, 55): 11.4,
 (13, 57): 9.5,
 (13, 59): 7.0,
 (13, 61): 8.2,
 (13, 63): 12.3,
 (13, 65): 11.0,
 (13, 67): 9.6,
 (13, 69): 16.8,
 (13, 71): 9.0,
 (13, 73): 7.0,
 (13, 75): 11.9,
 (13, 77): 10.0,
 (13, 79): 9.5,
 (13, 81): 12.1,
 (13, 83): 9.0,
 (13, 85): 10.1,
 (13, 87): 12.7,
 (13, 89): 10.7,
 (13, 91): 11.2,
 (13, 93): 10.1,
 (13, 95): 11.1,
 (13, 97): 11.4,
 (13, 99): 10.5,
 (13, 101): 6.7,
 (13, 103): 7.9,
 (13, 105): 12.2,
 (13, 107): 10.3,
 (13, 109): 8.9,
 (13, 111): 10.0,
 (13, 113): 8.4,
 (13, 115): 11.1,
 (13, 117): 8.6,
 (13, 119): 11.8,
 (13, 121): 10.7,
 (13, 123): 9.8,
 (13, 125): 11.1,
 (13, 127): 8.2,
 (13, 129): 13.1,
 (13, 131): 9.8,
 (13, 133): 11.1,
 (13, 135): 9.4,
 (13, 137): 9.4,
 (13, 139): 9.1,
 (13, 141): 17.7,
 (13, 143): 11.3,
 (13, 145): 7.2,
 (13, 147): 13.8,
 (13, 149): 12.4,
 (13, 151): 10.4,
 (13, 153): 7.3,
 (13, 155): 14.5,
 (13, 157): 10.9,
 (13, 159): 12.7,
 (13, 161): 13.5,
 (13, 163): 14.9,
 (13, 165): 19.6,
 (13, 167): 11.9,
 (13, 169): 8.6,
 (13, 171): 15.3,
 (13, 173): 8.4,
 (13, 175): 10.8,
 (13, 177): 7.9,
 (13, 179): 8.5,
 (13, 181): 10.3,
 (13, 183): 5.9,
 (13, 185): 8.2,
 (13, 187): 11.1,
 (13, 189): 12.1,
 (13, 191): 9.6,
 (13, 193): 13.0,
 (13, 195): 8.3,
 (13, 197): 9.9,
 (13, 199): 13.2,
 (13, 201): 8.7,
 (13, 205): 10.4,
 (13, 207): 10.2,
 (13, 209): 8.5,
 (13, 211): 9.8,
 (13, 213): 12.3,
 (13, 215): 9.2,
 (13, 217): 12.6,
 (13, 219): 6.2,
 (13, 221): 8.2,
 (13, 223): 10.7,
 (13, 225): 10.2,
 (13, 227): 10.8,
 (13, 229): 9.3,
 (13, 231): 11.8,
 (13, 233): 10.8,
 (13, 235): 7.1,
 (13, 237): 10.4,
 (13, 239): 11.8,
 (13, 241): 10.4,
 (13, 243): 13.0,
 (13, 245): 10.3,
 (13, 247): 12.0,
 (13, 249): 13.8,
 (13, 251): 13.7,
 (13, 253): 10.7,
 (13, 255): 15.4,
 (13, 257): 10.7,
 (13, 259): 10.7,
 (13, 261): 12.9,
 (13, 263): 9.8,
 (13, 265): 12.4,
 (13, 267): 8.7,
 (13, 269): 13.0,
 (13, 271): 16.2,
 (13, 273): 11.6,
 (13, 275): 9.3,
 (13, 277): 10.6,
 (13, 279): 9.8,
 (13, 281): 7.8,
 (13, 283): 11.9,
 (13, 285): 12.9,
 (13, 287): 13.0,
 (13, 289): 11.4,
 (13, 291): 9.0,
 (13, 293): 13.3,
 (13, 295): 9.6,
 (13, 297): 11.0,
 (13, 299): 10.7,
 (13, 301): 18.8,
 (13, 303): 14.0,
 (13, 305): 11.7,
 (13, 307): 9.1,
 (13, 309): 9.1,
 (13, 311): 9.5,
 (13, 313): 12.5,
 (13, 315): 11.6,
 (13, 317): 11.7,
 (13, 319): 10.7,
 (13, 321): 10.8,
 (15, 1): 10.8,
 (15, 3): 6.3,
 (15, 7): 9.6,
 (15, 9): 9.7,
 (16, 1): 9.1,
 (16, 3): 12.1,
 (16, 5): 8.4,
 (16, 7): 5.2,
 (16, 9): 12.1,
 (16, 11): 5.9,
 (16, 13): 7.7,
 (16, 15): 7.1,
 (16, 17): 9.5,
 (16, 19): 5.9,
 (16, 21): 12.0,
 (16, 23): 4.5,
 (16, 25): 11.0,
 (16, 27): 10.6,
 (16, 29): 6.0,
 (16, 31): 5.9,
 (16, 33): 4.1,
 (16, 35): 11.8,
 (16, 37): 3.9,
 (16, 39): 7.7,
 (16, 41): 4.0,
 (16, 43): 6.6,
 (16, 45): 10.4,
 (16, 47): 5.5,
 (16, 49): 8.3,
 (16, 51): 6.8,
 (16, 53): 5.9,
 (16, 55): 8.7,
 (16, 57): 5.9,
 (16, 59): 6.5,
 (16, 61): 5.2,
 (16, 63): 9.7,
 (16, 65): 5.5,
 (16, 67): 6.0,
 (16, 69): 5.5,
 (16, 71): 5.0,
 (16, 73): 4.1,
 (16, 75): 7.7,
 (16, 77): 6.7,
 (16, 79): 11.9,
 (16, 81): 5.1,
 (16, 83): 6.8,
 (16, 85): 11.4,
 (16, 87): 8.4,
 (17, 1): 7.9,
 (17, 3): 11.2,
 (17, 5): 9.3,
 (17, 7): 13.8,
 (17, 9): 4.5,
 (17, 11): 10.9,
 (17, 13): 9.5,
 (17, 15): 10.5,
 (17, 17): 7.3,
 (17, 19): 8.2,
 (17, 21): 9.9,
 (17, 23): 13.1,
 (17, 25): 11.4,
 (17, 27): 7.9,
 (17, 29): 9.1,
 (17, 31): 10.6,
 (17, 33): 10.5,
 (17, 35): 9.7,
 (17, 37): 9.2,
 (17, 39): 9.2,
 (17, 41): 9.1,
 (17, 43): 8.6,
 (17, 45): 10.7,
 (17, 47): 9.1,
 (17, 49): 7.9,
 (17, 51): 11.6,
 (17, 53): 10.4,
 (17, 55): 14.6,
 (17, 57): 12.5,
 (17, 59): 11.0,
 (17, 61): 9.2,
 (17, 63): 11.4,
 (17, 65): 9.3,
 (17, 67): 11.3,
 (17, 69): 12.8,
 (17, 71): 9.4,
 (17, 73): 8.6,
 (17, 75): 10.0,
 (17, 77): 7.3,
 (17, 79): 9.5,
 (17, 81): 10.0,
 (17, 83): 8.8,
 (17, 85): 8.1,
 (17, 87): 10.4,
 (17, 89): 9.9,
 (17, 91): 12.8,
 (17, 93): 10.4,
 (17, 95): 10.3,
 (17, 97): 10.0,
 (17, 99): 12.4,
 (17, 101): 10.3,
 (17, 103): 10.9,
 (17, 105): 10.7,
 (17, 107): 9.5,
 (17, 109): 7.7,
 (17, 111): 9.3,
 (17, 113): 7.4,
 (17, 115): 12.4,
 (17, 117): 10.5,
 (17, 119): 9.7,
 (17, 121): 11.9,
 (17, 123): 10.6,
 (17, 125): 14.3,
 (17, 127): 8.0,
 (17, 129): 7.8,
 (17, 131): 8.9,
 (17, 133): 7.8,
 (17, 135): 12.2,
 (17, 137): 8.4,
 (17, 139): 9.0,
 (17, 141): 11.9,
 (17, 143): 11.6,
 (17, 145): 11.9,
 (17, 147): 8.2,
 (17, 149): 8.1,
 (17, 151): 10.6,
 (17, 153): 11.9,
 (17, 155): 15.0,
 (17, 157): 9.4,
 (17, 159): 10.5,
 (17, 161): 9.5,
 (17, 163): 10.8,
 (17, 165): 11.2,
 (17, 167): 7.9,
 (17, 169): 6.6,
 (17, 171): 7.5,
 (17, 173): 10.0,
 (17, 175): 9.8,
 (17, 177): 11.6,
 (17, 179): 11.3,
 (17, 181): 10.8,
 (17, 183): 12.0,
 (17, 185): 10.3,
 (17, 187): 8.0,
 (17, 189): 8.0,
 (17, 191): 9.7,
 (17, 193): 8.6,
 (17, 195): 10.6,
 (17, 197): 9.9,
 (17, 199): 9.6,
 (17, 201): 15.5,
 (17, 203): 8.6,
 (18, 1): 13.4,
 (18, 3): 9.3,
 (18, 5): 8.8,
 (18, 7): 9.0,
 (18, 9): 13.3,
 (18, 11): 6.8,
 (18, 13): 7.8,
 (18, 15): 9.9,
 (18, 17): 10.5,
 (18, 19): 8.2,
 (18, 21): 9.6,
 (18, 23): 9.2,
 (18, 25): 10.5,
 (18, 27): 4.9,
 (18, 29): 8.9,
 (18, 31): 11.0,
 (18, 33): 12.4,
 (18, 35): 9.5,
 (18, 37): 8.0,
 (18, 39): 15.0,
 (18, 41): 13.4,
 (18, 43): 7.4,
 (18, 45): 11.6,
 (18, 47): 8.9,
 (18, 49): 11.2,
 (18, 51): 6.7,
 (18, 53): 11.1,
 (18, 55): 7.1,
 (18, 57): 6.1,
 (18, 59): 7.8,
 (18, 61): 7.8,
 (18, 63): 6.8,
 (18, 65): 12.0,
 (18, 67): 11.9,
 (18, 69): 11.1,
 (18, 71): 10.1,
 (18, 73): 8.7,
 (18, 75): 10.4,
 (18, 77): 9.5,
 (18, 79): 12.2,
 (18, 81): 7.4,
 (18, 83): 6.6,
 (18, 85): 11.0,
 (18, 87): 14.0,
 (18, 89): 9.4,
 (18, 91): 10.7,
 (18, 93): 11.1,
 (18, 95): 9.7,
 (18, 97): 8.4,
 (18, 99): 11.4,
 (18, 101): 6.3,
 (18, 103): 12.3,
 (18, 105): 5.6,
 (18, 107): 9.7,
 (18, 109): 7.5,
 (18, 111): 8.9,
 (18, 113): 14.5,
 (18, 115): 10.5,
 (18, 117): 9.2,
 (18, 119): 8.1,
 (18, 121): 8.3,
 (18, 123): 8.8,
 (18, 125): 8.7,
 (18, 127): 8.2,
 (18, 129): 7.0,
 (18, 131): 9.5,
 (18, 133): 8.2,
 (18, 135): 10.2,
 (18, 137): 9.1,
 (18, 139): 9.5,
 (18, 141): 10.4,
 (18, 143): 12.1,
 (18, 145): 8.8,
 (18, 147): 8.1,
 (18, 149): 12.6,
 (18, 151): 12.9,
 (18, 153): 9.3,
 (18, 155): 7.0,
 (18, 157): 8.5,
 (18, 159): 10.3,
 (18, 161): 8.6,
 (18, 163): 7.4,
 (18, 165): 10.8,
 (18, 167): 9.2,
 (18, 169): 12.0,
 (18, 171): 10.1,
 (18, 173): 6.9,
 (18, 175): 11.2,
 (18, 177): 10.9,
 (18, 179): 9.1,
 (18, 181): 9.4,
 (18, 183): 11.6,
 (19, 1): 5.1,
 (19, 3): 6.0,
 (19, 5): 9.3,
 (19, 7): 9.4,
 (19, 9): 5.1,
 (19, 11): 5.8,
 (19, 13): 5.8,
 (19, 15): 5.9,
 (19, 17): 5.0,
 (19, 19): 5.9,
 (19, 21): 5.5,
 (19, 23): 6.0,
 (19, 25): 5.4,
 (19, 27): 4.2,
 (19, 29): 5.8,
 (19, 31): 5.7,
 (19, 33): 6.7,
 (19, 35): 4.4,
 (19, 37): 8.4,
 (19, 39): 7.4,
 (19, 41): 6.2,
 (19, 43): 7.9,
 (19, 45): 7.7,
 (19, 47): 4.7,
 (19, 49): 5.1,
 (19, 51): 10.1,
 (19, 53): 6.6,
 (19, 55): 6.8,
 (19, 57): 8.2,
 (19, 59): 5.8,
 (19, 61): 6.0,
 (19, 63): 8.6,
 (19, 65): 8.5,
 (19, 67): 8.7,
 (19, 69): 7.0,
 (19, 71): 7.0,
 (19, 73): 6.3,
 (19, 75): 4.9,
 (19, 77): 5.6,
 (19, 79): 8.1,
 (19, 81): 9.0,
 (19, 83): 6.0,
 (19, 85): 4.4,
 (19, 87): 8.8,
 (19, 89): 8.6,
 (19, 91): 6.2,
 (19, 93): 5.8,
 (19, 95): 5.8,
 (19, 97): 7.7,
 (19, 99): 8.1,
 (19, 101): 8.7,
 (19, 103): 4.4,
 (19, 105): 6.3,
 (19, 107): 7.1,
 (19, 109): 5.6,
 (19, 111): 11.4,
 (19, 113): 6.5,
 (19, 115): 8.0,
 (19, 117): 6.0,
 (19, 119): 4.3,
 (19, 121): 5.8,
 (19, 123): 7.7,
 (19, 125): 5.7,
 (19, 127): 7.0,
 (19, 129): 4.3,
 (19, 131): 5.4,
 (19, 133): 7.1,
 (19, 135): 7.5,
 (19, 137): 8.7,
 (19, 139): 8.9,
 (19, 141): 5.3,
 (19, 143): 5.4,
 (19, 145): 8.7,
 (19, 147): 7.0,
 (19, 149): 4.7,
 (19, 151): 5.2,
 (19, 153): 6.2,
 (19, 155): 4.8,
 (19, 157): 6.6,
 (19, 159): 5.3,
 (19, 161): 4.7,
 (19, 163): 7.3,
 (19, 165): 3.9,
 (19, 167): 4.1,
 (19, 169): 4.5,
 (19, 171): 6.6,
 (19, 173): 6.7,
 (19, 175): 6.0,
 (19, 177): 8.0,
 (19, 179): 9.4,
 (19, 181): 5.8,
 (19, 183): 4.9,
 (19, 185): 6.4,
 (19, 187): 8.3,
 (19, 189): 9.1,
 (19, 191): 5.8,
 (19, 193): 5.7,
 (19, 195): 6.3,
 (19, 197): 8.4,
 (20, 1): 7.8,
 (20, 3): 7.9,
 (20, 5): 8.1,
 (20, 7): 5.1,
 (20, 9): 6.1,
 (20, 11): 6.5,
 (20, 13): 5.6,
 (20, 15): 7.2,
 (20, 17): 5.4,
 (20, 19): 8.4,
 (20, 21): 8.5,
 (20, 23): 3.7,
 (20, 25): 3.7,
 (20, 27): 4.2,
 (20, 29): 4.5,
 (20, 31): 5.7,
 (20, 33): 3.8,
 (20, 35): 7.6,
 (20, 37): 8.1,
 (20, 39): 3.3,
 (20, 41): 5.1,
 (20, 43): 8.8,
 (20, 45): 5.4,
 (20, 47): 4.4,
 (20, 49): 11.0,
 (20, 51): 3.6,
 (20, 53): 4.1,
 (20, 55): 4.3,
 (20, 57): 3.8,
 (20, 59): 7.1,
 (20, 61): 6.9,
 (20, 63): 3.5,
 (20, 65): 4.3,
 (20, 67): 4.2,
 (20, 69): 3.4,
 (20, 71): 4.5,
 (20, 73): 7.2,
 (20, 75): 4.2,
 (20, 77): 5.6,
 (20, 79): 7.4,
 (20, 81): 3.7,
 (20, 83): 4.2,
 (20, 85): 6.0,
 (20, 87): 6.7,
 (20, 89): 4.9,
 (20, 91): 6.8,
 (20, 93): 4.5,
 (20, 95): 6.3,
 (20, 97): 4.9,
 (20, 99): 7.8,
 (20, 101): 3.4,
 (20, 103): 7.3,
 (20, 105): 6.3,
 (20, 107): 8.4,
 (20, 109): 4.0,
 (20, 111): 5.7,
 (20, 113): 5.1,
 (20, 115): 6.3,
 (20, 117): 4.9,
 (20, 119): 4.2,
 (20, 121): 6.8,
 (20, 123): 5.8,
 (20, 125): 9.4,
 (20, 127): 6.8,
 (20, 129): 4.7,
 (20, 131): 4.3,
 (20, 133): 7.0,
 (20, 135): 4.0,
 (20, 137): 4.7,
 (20, 139): 7.0,
 (20, 141): 4.4,
 (20, 143): 6.5,
 (20, 145): 3.7,
 (20, 147): 6.0,
 (20, 149): 4.1,
 (20, 151): 5.3,
 (20, 153): 3.5,
 (20, 155): 6.3,
 (20, 157): 4.1,
 (20, 159): 5.1,
 (20, 161): 3.2,
 (20, 163): 7.3,
 (20, 165): 5.9,
 (20, 167): 4.6,
 (20, 169): 5.7,
 (20, 171): 3.2,
 (20, 173): 8.8,
 (20, 175): 5.1,
 (20, 177): 6.4,
 (20, 179): 3.2,
 (20, 181): 3.9,
 (20, 183): 4.3,
 (20, 185): 6.1,
 (20, 187): 3.4,
 (20, 189): 5.3,
 (20, 191): 9.0,
 (20, 193): 3.6,
 (20, 195): 3.6,
 (20, 197): 6.6,
 (20, 199): 5.9,
 (20, 201): 4.5,
 (20, 203): 3.5,
 (20, 205): 10.2,
 (20, 207): 8.9,
 (20, 209): 10.4,
 (21, 1): 10.1,
 (21, 3): 14.3,
 (21, 5): 10.9,
 (21, 7): 10.2,
 (21, 9): 11.6,
 (21, 11): 13.3,
 (21, 13): 12.5,
 (21, 15): 9.2,
 (21, 17): 9.1,
 (21, 19): 8.3,
 ...}
counties = {
    code: county for code, county in counties.items() if county["state"] == "tx"
}

county_xs = [county["lons"] for county in counties.values()]
county_ys = [county["lats"] for county in counties.values()]

county_names = [county['name'] for county in counties.values()]
county_rates = [unemployment[county_id] for county_id in counties]
color_mapper = LogColorMapper(palette=palette)

data=dict(
    x=county_xs,
    y=county_ys,
    name=county_names,
    rate=county_rates,
)

TOOLS = "pan,wheel_zoom,reset,hover,save"

p = figure(
    title="Texas Unemployment, 2009", tools=TOOLS,
    x_axis_location=None, y_axis_location=None,
    tooltips=[
        ("Name", "@name"), ("Unemployment rate)", "@rate%"), ("(Long, Lat)", "($x, $y)")
    ])
p.grid.grid_line_color = None
p.hover.point_policy = "follow_mouse"

p.patches('x', 'y', source=data,
          fill_color={'field': 'rate', 'transform': color_mapper},
          fill_alpha=0.7, line_color="white", line_width=0.5)



# save to file
output_file('bokeh-example.html')

# and/or show in browser
show(p)

An example with plotly

plotly is an extensive visualization library that is part of a larger ecosystem to build dashboards and apps. But what’s nice is that since pandas 0.25, you can even use it as a drop-in replacement for matplotlib as backend. It’s just one line: pd.options.plotting.backend = "plotly"

Read more here: https://plotly.com/python/pandas-backend/

pd.options.plotting.backend = "plotly"

mediause['average'] = mediause[['radio','tv','newspaper','internet']].mean(axis=1)
# we sample 50 points here just to make the graph clearer, of course that doesn't make much sense conceptually here
fig = mediause.sample(50).plot(x='age', y='average', kind='scatter')
fig.show()
fig.write_html("plotly-example.html")
# let's add some more data to the hover-over box
# look at https://towardsdatascience.com/visualization-with-plotly-express-comprehensive-guide-eb5ee4b50b57 for more info
# e.g., we can also specify color = 'varname', size = 'varname' etc. - very much like in seaborn
fig = mediause.sample(50).plot(x='age', y='average', hover_data={"gender":True},kind='scatter')
fig.show()
mediause.internet.hist()

Publishing interactivity

Publishing and distributing your STATIC visualizations is straightforward (see week 4 of this course). You can simply save them in any format you like (e.g., .png (better than .jpg for text and sharp lines), or as a vector graphic (e.g., .svg) that allows loss-free scaling. For example, we could use plt.save_fig() for that purpose.

This file, then, can be freely used in any online or offline publication.

But how can we do this online? It’s one thing to make a nice interactive visualization in your browser, it’s another thing to share them with the world.

SVG graphics

One approach are SVG graphics. That’s the route we took in the pygal example above. As you see, you can just open the file in any browser, and the interactive elements (hovering over the bars with your mouse shows the values) work.

However, there is one problem with this approach: First, the possibilities types of interactivity possible are a bit limited. Second, and more importantly: SVG graphics are sometimes seen as a security risk (because one could construct a malicious svg file that executes unwanted code); and therefore, many platforms restrict their use (for instance, Wordpress - although you can (partly) circumvent this, for instance by installing a svg plugin).

If you build your own website from scratch, that’s less of a problem, of course.

Here, you can find an example of how to embed svg graphics in a web page: http://www.pygal.org/en/stable/documentation/web.html

JavaScript (client-side)

The bokeh example above takes a different approach: It generates an HTML file and java script code that then is used to render the interactive graphic in the users’ browser. That means that if we distribute the HTML file (and, for instance, upload it to our own website; I did it here), anyone can use it in their browser.

It requires a bit more fiddling, though, to display such a thing inline (for instance, like embedding a picture within a wordpress blog). With a bit of HTML knowledge, though, you can get there. You can find a lot of (free) HTML tutorials online.

Server-side approaches

Both approaches outlined above are self-contained: They include all data, all calculations are already made, etc. Especially if you have very large data, or when you want to actually run some python code based on the user input, you will need to run your own (bokeh-) server. That’s a cool thing to do (and a nice project to pursue, if you want to experiment a bit), but out of scope for this class.

Exercise

The example below is from the official bokeh tutorial (https://mybinder.org/v2/gh/bokeh/bokeh-notebooks/master?filepath=tutorial%2F00%20-%20Introduction%20and%20Setup.ipynb ). It plots a complex chart with intearctive hover.

Try to understand the code (in broad lines) and modify it to explore what happens. Construct a different visualization, or use other (own?) data.

# import modules and prepare example dataset

from bokeh.models import ColumnDataSource, HoverTool
from bokeh.plotting import figure
from bokeh.sampledata.autompg import autompg_clean as df
from bokeh.transform import factor_cmap

df.cyl = df.cyl.astype(str)
df.yr = df.yr.astype(str)
df
mpg cyl displ hp weight accel yr origin name mfr
0 18.0 8 307.0 130 3504 12.0 70 North America chevrolet chevelle malibu chevrolet
1 15.0 8 350.0 165 3693 11.5 70 North America buick skylark 320 buick
2 18.0 8 318.0 150 3436 11.0 70 North America plymouth satellite plymouth
3 16.0 8 304.0 150 3433 12.0 70 North America amc rebel sst amc
4 17.0 8 302.0 140 3449 10.5 70 North America ford torino ford
... ... ... ... ... ... ... ... ... ... ...
387 27.0 4 140.0 86 2790 15.6 82 North America ford mustang gl ford
388 44.0 4 97.0 52 2130 24.6 82 Europe vw pickup volkswagen
389 32.0 4 135.0 84 2295 11.6 82 North America dodge rampage dodge
390 28.0 4 120.0 79 2625 18.6 82 North America ford ranger ford
391 31.0 4 119.0 82 2720 19.4 82 North America chevy s-10 chevrolet

392 rows × 10 columns

group = df.groupby(by=['cyl', 'mfr'])
source = ColumnDataSource(group)

p = figure(plot_width=800, plot_height=300, title="Mean MPG by # Cylinders and Manufacturer",
           x_range=group, toolbar_location=None, tools="")

p.xgrid.grid_line_color = None
p.xaxis.axis_label = "Manufacturer grouped by # Cylinders"
p.xaxis.major_label_orientation = 1.2

index_cmap = factor_cmap('cyl_mfr', palette=['#2b83ba', '#abdda4', '#ffffbf', '#fdae61', '#d7191c'], 
                         factors=sorted(df.cyl.unique()), end=1)

p.vbar(x='cyl_mfr', top='mpg_mean', width=1, source=source,
       line_color="white", fill_color=index_cmap, 
       hover_line_color="darkgrey", hover_fill_color=index_cmap)

p.add_tools(HoverTool(tooltips=[("MPG", "@mpg_mean"), ("Cyl, Mfr", "@cyl_mfr")]))

show(p)

To give you a little help, I made one with our mediause dataset:

group = mediause.groupby('education')
source = ColumnDataSource(group)

p = figure()
p.vbar(x='education', top='internet_mean', width=1, source=source,
       line_color="white")

p.add_tools(HoverTool(tooltips=[("internet use", "@internet_mean"), ("education", "@education")]))

show(p)
group['internet'].describe()
count mean std min 25% 50% 75% max
education
1.0 68.0 1.397059 2.266826 0.0 0.0 0.0 2.0 7.0
2.0 323.0 1.829721 2.498220 0.0 0.0 0.0 3.0 7.0
3.0 214.0 2.093458 2.589371 0.0 0.0 1.0 4.0 7.0
4.0 667.0 2.499250 2.752217 0.0 0.0 1.0 5.0 7.0
5.0 178.0 2.589888 2.650085 0.0 0.0 2.0 5.0 7.0
6.0 396.0 3.520202 2.841304 0.0 1.0 4.0 7.0 7.0
7.0 219.0 4.059361 2.705947 0.0 1.5 5.0 7.0 7.0
mediause_nice = mediause.copy()
mediause_nice['education'].replace({1: '1 basis', 2:'2 vmbo', 3: '3 vmbo-t', 4: '4 mbo', 5: '5 hbo', 6:'6 wo-bachelor',
                               7:'7 wo-master'}, inplace=True)

group = mediause_nice.groupby('education')
source = ColumnDataSource(group)

p = figure(x_range=group)
p.vbar(x='education', top='internet_mean', width=1, source=source,
       line_color="white")

p.add_tools(HoverTool(tooltips=[("internet use", "@internet_mean"), ("education", "@education")]))

show(p)