We saw in our previous notebook how to create visualisations using matplotlib, seaborn, and pandas - however, in most cases these were static. We did get some interaction through the 3D plots and through using the Plotly library. Here, we are going to pursue this further, and look at how we can incorporate interaction and animation into our tools.
In particular, interaction techniques are useful for creatng dashboards (visual analytics) interfaces. Animations can be useful for conveying the story, by linking multiple still images together or by showing the analytical process.
In this example notebook, we demonstrate how to create interactive widgets that can be used to filter data from a dataframe, either based on range selection or by item selection. We also demonstrate how an animated GIF can be constructed by taking frames of a plot to build an animation. We use a live data set based on COVID-19 to illustrate the concepts in this notebook.
Further details are in the following blog post: https://towardsdatascience.com/interactive-controls-for-jupyter-notebooks-f5c94829aee6
import pandas as pd
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
!pip install ipywidgets
Requirement already satisfied: ipywidgets in c:\python39\lib\site-packages (7.6.5) Requirement already satisfied: nbformat>=4.2.0 in c:\python39\lib\site-packages (from ipywidgets) (5.1.3) Requirement already satisfied: widgetsnbextension~=3.5.0 in c:\python39\lib\site-packages (from ipywidgets) (3.5.2) Requirement already satisfied: ipykernel>=4.5.1 in c:\python39\lib\site-packages (from ipywidgets) (6.5.0) Requirement already satisfied: ipython-genutils~=0.2.0 in c:\python39\lib\site-packages (from ipywidgets) (0.2.0) Requirement already satisfied: ipython>=4.0.0 in c:\python39\lib\site-packages (from ipywidgets) (7.29.0) Requirement already satisfied: traitlets>=4.3.1 in c:\python39\lib\site-packages (from ipywidgets) (5.1.1) Requirement already satisfied: jupyterlab-widgets>=1.0.0 in c:\python39\lib\site-packages (from ipywidgets) (1.0.2) Requirement already satisfied: debugpy<2.0,>=1.0.0 in c:\python39\lib\site-packages (from ipykernel>=4.5.1->ipywidgets) (1.5.1) Requirement already satisfied: tornado<7.0,>=4.2 in c:\python39\lib\site-packages (from ipykernel>=4.5.1->ipywidgets) (6.1) Requirement already satisfied: matplotlib-inline<0.2.0,>=0.1.0 in c:\python39\lib\site-packages (from ipykernel>=4.5.1->ipywidgets) (0.1.3) Requirement already satisfied: jupyter-client<8.0 in c:\python39\lib\site-packages (from ipykernel>=4.5.1->ipywidgets) (7.0.6) Requirement already satisfied: decorator in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (4.4.2) Requirement already satisfied: pygments in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (2.10.0) Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (3.0.22) Requirement already satisfied: setuptools>=18.5 in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (57.4.0) Requirement already satisfied: backcall in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (0.2.0) Requirement already satisfied: colorama in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (0.4.4) Requirement already satisfied: jedi>=0.16 in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (0.18.0) Requirement already satisfied: pickleshare in c:\python39\lib\site-packages (from ipython>=4.0.0->ipywidgets) (0.7.5) Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in c:\python39\lib\site-packages (from nbformat>=4.2.0->ipywidgets) (3.2.0) Requirement already satisfied: jupyter-core in c:\python39\lib\site-packages (from nbformat>=4.2.0->ipywidgets) (4.9.1) Requirement already satisfied: notebook>=4.4.1 in c:\python39\lib\site-packages (from widgetsnbextension~=3.5.0->ipywidgets) (6.4.5) Requirement already satisfied: parso<0.9.0,>=0.8.0 in c:\python39\lib\site-packages (from jedi>=0.16->ipython>=4.0.0->ipywidgets) (0.8.2) Requirement already satisfied: six>=1.11.0 in c:\python39\lib\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets) (1.16.0) Requirement already satisfied: pyrsistent>=0.14.0 in c:\python39\lib\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets) (0.18.0) Requirement already satisfied: attrs>=17.4.0 in c:\python39\lib\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets) (21.2.0) Requirement already satisfied: nest-asyncio>=1.5 in c:\python39\lib\site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets) (1.5.1) Requirement already satisfied: python-dateutil>=2.1 in c:\python39\lib\site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets) (2.8.2) Requirement already satisfied: entrypoints in c:\python39\lib\site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets) (0.3) Requirement already satisfied: pyzmq>=13 in c:\python39\lib\site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets) (22.3.0) Requirement already satisfied: pywin32>=1.0 in c:\python39\lib\site-packages (from jupyter-core->nbformat>=4.2.0->ipywidgets) (302) Requirement already satisfied: argon2-cffi in c:\python39\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (21.1.0) Requirement already satisfied: terminado>=0.8.3 in c:\python39\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.12.1) Requirement already satisfied: jinja2 in c:\python39\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (3.0.3) Requirement already satisfied: Send2Trash>=1.5.0 in c:\python39\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (1.8.0) Requirement already satisfied: prometheus-client in c:\python39\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.12.0) Requirement already satisfied: nbconvert in c:\python39\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (6.3.0) Requirement already satisfied: wcwidth in c:\python39\lib\site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython>=4.0.0->ipywidgets) (0.2.5) Requirement already satisfied: pywinpty>=1.1.0 in c:\python39\lib\site-packages (from terminado>=0.8.3->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (1.1.5) Requirement already satisfied: cffi>=1.0.0 in c:\python39\lib\site-packages (from argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (1.15.0) Requirement already satisfied: MarkupSafe>=2.0 in c:\python39\lib\site-packages (from jinja2->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (2.0.1) Requirement already satisfied: bleach in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (4.1.0) Requirement already satisfied: jupyterlab-pygments in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.1.2) Requirement already satisfied: defusedxml in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.7.1) Requirement already satisfied: testpath in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.5.0) Requirement already satisfied: mistune<2,>=0.8.1 in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.8.4) Requirement already satisfied: pandocfilters>=1.4.1 in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (1.5.0) Requirement already satisfied: nbclient<0.6.0,>=0.5.0 in c:\python39\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.5.8) Requirement already satisfied: pycparser in c:\python39\lib\site-packages (from cffi>=1.0.0->argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (2.21) Requirement already satisfied: packaging in c:\python39\lib\site-packages (from bleach->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (21.2) Requirement already satisfied: webencodings in c:\python39\lib\site-packages (from bleach->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (0.5.1) Requirement already satisfied: pyparsing<3,>=2.0.2 in c:\python39\lib\site-packages (from packaging->bleach->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets) (2.4.7)
import ipywidgets as widgets
from ipywidgets import interact, interact_manual
df = pd.read_csv('https://coronavirus.data.gov.uk/downloads/csv/coronavirus-cases_latest.csv')
df
Area name | Area code | Area type | Specimen date | Daily lab-confirmed cases | Cumulative lab-confirmed cases | Cumulative lab-confirmed cases rate | |
---|---|---|---|---|---|---|---|
0 | Stoke-on-Trent | E06000021 | ltla | 2021-04-26 | 5 | 20083 | 7833.4 |
1 | Staffordshire Moorlands | E07000198 | ltla | 2021-04-26 | 5 | 5351 | 5436.1 |
2 | Hackney and City of London | E09000012 | ltla | 2021-04-26 | 5 | 21672 | 7451.5 |
3 | Staffordshire Moorlands | E07000198 | ltla | 2021-04-25 | 6 | 5346 | 5431.0 |
4 | Newark and Sherwood | E07000175 | ltla | 2021-04-26 | 4 | 7292 | 5956.5 |
... | ... | ... | ... | ... | ... | ... | ... |
45292 | Norfolk | E10000020 | utla | 2021-01-13 | 621 | 28630 | 3153.9 |
45293 | Norfolk | E10000020 | utla | 2021-01-12 | 671 | 28009 | 3085.5 |
45294 | Norfolk | E10000020 | utla | 2021-01-11 | 795 | 27338 | 3011.6 |
45295 | Norfolk | E10000020 | utla | 2021-01-10 | 504 | 26543 | 2924.0 |
45296 | Norfolk | E10000020 | utla | 2021-01-09 | 392 | 26039 | 2868.5 |
45297 rows × 7 columns
@interact
def show_articles_more_than(column='Daily lab-confirmed cases', x=20):
return df.loc[df[column] > x]
interactive(children=(Text(value='Daily lab-confirmed cases', description='column'), IntSlider(value=20, descr…
# What if we want a custom min-max range for our slider?
# https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html
@interact
def show_articles_more_than(column='Daily lab-confirmed cases', x=widgets.IntSlider(min=0, max=1000, step=1, value=10)):
return df.loc[df[column] > x]
interactive(children=(Text(value='Daily lab-confirmed cases', description='column'), IntSlider(value=10, descr…
@interact
def show_for_place(column='Area name', x=sorted(df['Area name'].unique())):
return df.loc[df[column] == x]
interactive(children=(Text(value='Area name', description='column'), Dropdown(description='x', options=('Arun'…
!pip install moviepy
import glob
import moviepy.editor as mpy
Requirement already satisfied: moviepy in c:\python39\lib\site-packages (1.0.3) Requirement already satisfied: numpy>=1.17.3 in c:\python39\lib\site-packages (from moviepy) (1.21.2) Requirement already satisfied: requests<3.0,>=2.8.1 in c:\python39\lib\site-packages (from moviepy) (2.26.0) Requirement already satisfied: proglog<=1.0.0 in c:\python39\lib\site-packages (from moviepy) (0.1.9) Requirement already satisfied: tqdm<5.0,>=4.11.2 in c:\python39\lib\site-packages (from moviepy) (4.62.3) Requirement already satisfied: decorator<5.0,>=4.0.2 in c:\python39\lib\site-packages (from moviepy) (4.4.2) Requirement already satisfied: imageio-ffmpeg>=0.2.0 in c:\python39\lib\site-packages (from moviepy) (0.4.5) Requirement already satisfied: imageio<3.0,>=2.5 in c:\python39\lib\site-packages (from moviepy) (2.12.0) Requirement already satisfied: pillow>=8.3.2 in c:\python39\lib\site-packages (from imageio<3.0,>=2.5->moviepy) (8.4.0) Requirement already satisfied: charset-normalizer~=2.0.0 in c:\python39\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (2.0.7) Requirement already satisfied: certifi>=2017.4.17 in c:\python39\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (2021.10.8) Requirement already satisfied: idna<4,>=2.5 in c:\python39\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (2.10) Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\python39\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (1.26.7) Requirement already satisfied: colorama in c:\python39\lib\site-packages (from tqdm<5.0,>=4.11.2->moviepy) (0.4.4)
plt.figure(figsize=(20,10))
data = df[df['Area type'] == 'utla']
plt.xticks(rotation=90)
plt.plot(data.groupby('Specimen date').sum()['Daily lab-confirmed cases'])
[<matplotlib.lines.Line2D at 0x20eff4d7700>]
data = df[df['Area type'] == 'utla']
output = data.groupby('Specimen date').sum()['Daily lab-confirmed cases']
output
Specimen date 2021-01-09 392 2021-01-10 504 2021-01-11 795 2021-01-12 671 2021-01-13 621 ... 2021-04-17 13 2021-04-18 21 2021-04-20 25 2021-04-21 30 2021-04-26 26 Name: Daily lab-confirmed cases, Length: 69, dtype: int64
for i in range(len(output)):
oo = output[:i]
plt.xticks(rotation=90)
plt.plot(oo)
plt.savefig(f"./pngs/{i}.png")
plt.close()
import os
gif_name = 'COVID.gif'
fps = 6
file_list = sorted(glob.glob('./pngs/*.png'), key=os.path.getmtime)
clip = mpy.ImageSequenceClip(file_list, fps=fps)
clip.write_gif('{}'.format(gif_name), fps=fps)
MoviePy - Building file COVID.gif with imageio.