{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# COVID-19 statistics in China (except Hubei)\n", "Data comes from https://tinyurl.com/s6gsq5y" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import geopandas as gpd\n", "from sklearn import cluster\n", "\n", "from ipywidgets import widgets\n", "from IPython.display import display\n", "\n", "from lets_plot import *" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'load_lets_plot_js' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32mC:\\Temp/ipykernel_6776/2399501846.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mload_lets_plot_js\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mNameError\u001b[0m: name 'load_lets_plot_js' is not defined" ] } ], "source": [ "load_lets_plot_js()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib notebook" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "DATA_URL = 'https://docs.google.com/spreadsheets/d/1itaohdPiAeniCXNlntNztZ_oRvjh0HsGuJXUJWET008/export?format=csv&id=1itaohdPiAeniCXNlntNztZ_oRvjh0HsGuJXUJWET008&gid=0'\n", "MAX_CLUSTERS_COUNT = 20\n", "OUTCOMES = ['diseased', 'died', 'discharged', 'stable']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def player_widget(plots, *, fps=1):\n", " interval = max(1, int(1000 / fps))\n", " player = widgets.Play(min=0, max=len(plots) - 1, step=1, value=0, interval=interval)\n", " slider = widgets.IntSlider(min=0, max=len(plots) - 1, step=1, value=0)\n", " widgets.jslink((player, 'value'), (slider, 'value'))\n", " widget = widgets.HBox([player, slider])\n", " iout = widgets.interactive_output(lambda n, m: display(plots[n]), {'n': slider, 'm': player})\n", " return display(widget, iout)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def find_best_clustering(shapely_points, *, max_clusters_count=1, clusters_limit_proportion=.02, \\\n", " attempts_count=1, method=cluster.KMeans):\n", " points = shapely_points.apply(lambda p: [p.x, p.y]).to_list()\n", " max_clusters_count = min(max_clusters_count, len(set([str(p) for p in points])))\n", " if max_clusters_count < 1:\n", " return None\n", " for n in range(max_clusters_count, 0, -1):\n", " clustering = method(n_clusters=n, n_jobs=attempts_count).fit(points)\n", " clusters, counts = np.unique(clustering.labels_, return_counts=True)\n", " if clusters_limit_proportion <= np.min(counts) / np.max(counts):\n", " return clustering\n", " assert(False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def append_cluster_column(gdf, *, distinguished_columns=[], max_clusters_count=1, cluster_column_name='cluster'):\n", " if any(distinguished_columns):\n", " column = distinguished_columns[0]\n", " return pd.concat([\n", " append_cluster_column(gdf[gdf[column] == value].copy(), \\\n", " distinguished_columns=distinguished_columns[1:], \\\n", " max_clusters_count=max_clusters_count, \\\n", " cluster_column_name=cluster_column_name)\n", " for value in gdf[column].value_counts().keys()\n", " ])\n", " else:\n", " gdf[cluster_column_name] = find_best_clustering(gdf.geometry, max_clusters_count=max_clusters_count).labels_\n", " return gdf" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_clusters_gdf(gdf, outcome, current_date):\n", " gdf = gdf[gdf.outcome == outcome].copy()\n", " actual_gdf = gdf[gdf.date_confirmation<=current_date]\n", " if outcome in ['discharged', 'died']:\n", " actual_gdf = actual_gdf[actual_gdf.date_death_or_discharge<=current_date]\n", " \n", " vc = actual_gdf.cluster.value_counts()\n", " clusters, counts = vc.keys(), vc.values\n", " geometry = [gdf[gdf.cluster == cluster].unary_union.centroid for cluster in clusters]\n", " \n", " return gpd.GeoDataFrame(dict(cluster=clusters, \\\n", " count=counts, \\\n", " outcome=[outcome]*len(clusters), \\\n", " date=[current_date]*len(clusters), \\\n", " geometry=geometry))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Read the map polygon\n", "world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))\n", "china = world[world.name == 'China']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Prepare dataframe\n", "columns = ['date_confirmation', 'outcome', 'date_death_or_discharge', 'country', 'latitude', 'longitude']\n", "except_hubei_data = pd.read_csv(DATA_URL)\n", "df = pd.DataFrame(except_hubei_data)[columns]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Clean data\n", "df = df[~df.latitude.isna()]\n", "df = df[~df.longitude.isna()]\n", "df = df[~df.date_confirmation.isna()]\n", "df = df[df.country == 'China']\n", "df = df[~(((df.outcome=='discharged')|(df.outcome=='died'))&df.date_death_or_discharge.isna())]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Fix data\n", "df.latitude = df.latitude.astype(float)\n", "df.longitude = df.longitude.astype(float)\n", "df.date_confirmation = pd.to_datetime(df.date_confirmation, dayfirst=True, errors='coerce')\\\n", " .apply(lambda dt: dt.replace(year=2020))\n", "df.date_death_or_discharge = pd.to_datetime(df.date_death_or_discharge, dayfirst=True, errors='coerce')\\\n", " .apply(lambda dt: dt.replace(year=2020))\n", "df.outcome = df.outcome.replace({'discharge': 'discharged'})\\\n", " .apply(lambda outcome: outcome if outcome in OUTCOMES else 'diseased')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Prepare geodataframe\n", "gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.longitude, df.latitude))\n", "gdf = gdf[gdf.within(china.iloc[0].geometry)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Add clusters by geoposition\n", "gdf = append_cluster_column(gdf, distinguished_columns=['outcome'], max_clusters_count=MAX_CLUSTERS_COUNT)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Prepare clusterized geodataframe\n", "clusters_gdf = pd.concat([\n", " pd.concat([\n", " get_clusters_gdf(gdf, outcome=outcome, current_date=current_date)\n", " for current_date in gdf.date_confirmation.sort_values().unique()\n", " ])\n", " for outcome in OUTCOMES\n", "])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Prepare list of plots that would be frames of the animation\n", "p = ggplot() + \\\n", " geom_polygon(data=china, fill='#d6d6d6') + \\\n", " theme(legend_position=(.15, .15), axis_title='blank', axis_text='blank', axis_ticks='blank', axis_line='blank') + \\\n", " ggsize(600, 600)\n", "\n", "limit = clusters_gdf['count'].max()\n", "plots = []\n", "for current_date in gdf.date_confirmation.sort_values().unique():\n", " current_clusters_gdf = clusters_gdf[clusters_gdf.date == current_date]\n", " plots.append(\n", " p + \\\n", " geom_point(aes(size='count', color='outcome'), data=current_clusters_gdf) + \\\n", " scale_size(name='', limits=[0, limit]) + \\\n", " scale_color_manual(values=['#cf3c38', 'black', '#90c73e', '#4cc5db']) + \\\n", " ggtitle('COVID-19 on ' + np.datetime_as_string(current_date, unit='D'))\n", " )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "player_widget(plots)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" }, "pycharm": { "stem_cell": { "cell_type": "raw", "metadata": { "collapsed": false }, "source": [] } }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "03d62577de3d4fd7965b674926a04e76": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "06babde1052840a7b779f8f34da28ae4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "07daf44749e6445786a59c3e94c9341b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "0ab2a42cbc8740dba1fa5d7122588ac3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "PlayModel", "state": { "interval": 1000, "layout": "IPY_MODEL_e76b3bd38ee14206b750b9981b770199", "max": 38, "style": "IPY_MODEL_f3b9e292accf4e9287986fc17edb3676", "value": 38 } }, "0d323541d9924b1ebf17d1c2b5ec4d86": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "1988bf23a64a441b89848ced0ca2a584": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "1b6417b807f8477a9069570ffcf8208b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "PlayModel", "state": { "interval": 1000, "layout": "IPY_MODEL_232bf4a0898f42e9acaeb4744cc19235", "max": 38, "style": "IPY_MODEL_9290093586c842fd882140f4eae9ce88", "value": 38 } }, "232bf4a0898f42e9acaeb4744cc19235": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "3542778bda134f02b196fed5ee4ba236": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "layout": "IPY_MODEL_03d62577de3d4fd7965b674926a04e76", "max": 38, "style": "IPY_MODEL_45f4d01d572642e1afbc9d0276429825", "value": 23 } }, "3da72335e55049c3b971a2d8f3e94c70": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "4300314b81c144a0a831326fc957befc": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "LinkModel", "state": { "source": [ "IPY_MODEL_d8125145d48a46d193d8bf39b5bcfa02", "value" ], "target": [ "IPY_MODEL_3542778bda134f02b196fed5ee4ba236", "value" ] } }, "45f4d01d572642e1afbc9d0276429825": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "483ed026dde44c3b818bbc8b35d27659": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "52f3fd119ede4ef69cac3af9365f25f6": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "54811c02f756439693b4dab8457271b6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "layout": "IPY_MODEL_1988bf23a64a441b89848ced0ca2a584", "max": 38, "style": "IPY_MODEL_8d1e66461e734df0a63b1d448f9a0edf", "value": 16 } }, "55b57fa4b212464e97dbce0c688cb0d9": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "615f053348b3433a93c903081a6b725c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "6275369d7021466886edc1d2337b818c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "LinkModel", "state": { "source": [ "IPY_MODEL_1b6417b807f8477a9069570ffcf8208b", "value" ], "target": [ "IPY_MODEL_752d0c2721b24d7792ad9e93554b6cdc", "value" ] } }, "6a4d9a0acba146a09f4ff03b1cd858ec": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_e0a0579e8f474aa59c66cd5f1d084fc1", "IPY_MODEL_709b6d01737a48b6b53bd3c673ea9a23" ], "layout": "IPY_MODEL_06babde1052840a7b779f8f34da28ae4" } }, "6c6e876da2e24a618237dd2f5f91923d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "709b6d01737a48b6b53bd3c673ea9a23": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "layout": "IPY_MODEL_d1da66120ad244f1b7933bf3f1372942", "max": 38, "style": "IPY_MODEL_bcc675b4ef624247ae68f418b451d4a8", "value": 38 } }, "747edf0666ab4b6d9a4363d783755282": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "layout": "IPY_MODEL_eab364485426408d8967a1018da1760d", "max": 38, "style": "IPY_MODEL_dce3a046b15e41a782c3564ce908df9e", "value": 38 } }, "752d0c2721b24d7792ad9e93554b6cdc": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "layout": "IPY_MODEL_dbbd30b1fa3145b491e7ba22e299f40d", "max": 38, "style": "IPY_MODEL_8bc4688d1ad64d1e94f9cd9c5dc1876e", "value": 38 } }, "79d8bf641c984298bb1880441e7f8a9a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "81a7b4f2f4f34516b4265dd2cea74c72": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_d8125145d48a46d193d8bf39b5bcfa02", "IPY_MODEL_3542778bda134f02b196fed5ee4ba236" ], "layout": "IPY_MODEL_9a3de8bd8daa4e01a2b8324373baa4b1" } }, "81d76d09444946fda40b4216ce2a1e51": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_1b6417b807f8477a9069570ffcf8208b", "IPY_MODEL_752d0c2721b24d7792ad9e93554b6cdc" ], "layout": "IPY_MODEL_483ed026dde44c3b818bbc8b35d27659" } }, "8bc4688d1ad64d1e94f9cd9c5dc1876e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "8d1e66461e734df0a63b1d448f9a0edf": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "90a2559e59fa4f4baa1936e074773dfa": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "LinkModel", "state": { "source": [ "IPY_MODEL_e0a0579e8f474aa59c66cd5f1d084fc1", "value" ], "target": [ "IPY_MODEL_709b6d01737a48b6b53bd3c673ea9a23", "value" ] } }, "9290093586c842fd882140f4eae9ce88": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "9a3de8bd8daa4e01a2b8324373baa4b1": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "aba4e48ef7c540bc87a8632339338a6d": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_55b57fa4b212464e97dbce0c688cb0d9", "outputs": [ { "data": { "text/html": "
\n ", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "b03b0800c74741a4b221b472d210a5a3": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b4e0d03e634a483b9fd9d99ef9c4f55d": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_615f053348b3433a93c903081a6b725c", "outputs": [ { "data": { "text/html": "
\n ", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "b807750af1d141d59a04aed88f6a0552": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "LinkModel", "state": { "source": [ "IPY_MODEL_0ab2a42cbc8740dba1fa5d7122588ac3", "value" ], "target": [ "IPY_MODEL_747edf0666ab4b6d9a4363d783755282", "value" ] } }, "bcc675b4ef624247ae68f418b451d4a8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "be804510102e43c3aa42aa685194d1cc": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "bf7242a655874eb69b829c25effe0b9c": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_0d323541d9924b1ebf17d1c2b5ec4d86", "outputs": [ { "data": { "text/html": "
\n ", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "c5d3c5d247454d808aac4a8e3f5a8ea0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "LinkModel", "state": { "source": [ "IPY_MODEL_fd9ce3a5f6b244a2aab6a0b4c3b5a2cf", "value" ], "target": [ "IPY_MODEL_54811c02f756439693b4dab8457271b6", "value" ] } }, "ce8dbb234f284b2ba744298948e64e23": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "cfd475d8336f4fb5b5b3950c26d41ffb": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_07daf44749e6445786a59c3e94c9341b", "outputs": [ { "data": { "text/html": "
\n ", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "d1da66120ad244f1b7933bf3f1372942": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d3316de7499e45e8a19e378c294187cf": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "d8125145d48a46d193d8bf39b5bcfa02": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "PlayModel", "state": { "_playing": true, "interval": 1000, "layout": "IPY_MODEL_be804510102e43c3aa42aa685194d1cc", "max": 38, "style": "IPY_MODEL_79d8bf641c984298bb1880441e7f8a9a", "value": 23 } }, "dbbd30b1fa3145b491e7ba22e299f40d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "dce3a046b15e41a782c3564ce908df9e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "e0a0579e8f474aa59c66cd5f1d084fc1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "PlayModel", "state": { "interval": 1000, "layout": "IPY_MODEL_e371f9cab5e7484790abd8044dcefb17", "max": 38, "style": "IPY_MODEL_ce8dbb234f284b2ba744298948e64e23", "value": 38 } }, "e371f9cab5e7484790abd8044dcefb17": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "e76b3bd38ee14206b750b9981b770199": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "eab364485426408d8967a1018da1760d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "efdbbda054b546b89155758159a51c2c": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_3da72335e55049c3b971a2d8f3e94c70", "outputs": [ { "data": { "text/html": "
\n ", "text/plain": "" }, "metadata": {}, "output_type": "display_data" } ] } }, "f3b9e292accf4e9287986fc17edb3676": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "f5366755650548649a30d5be85bddc51": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_fd9ce3a5f6b244a2aab6a0b4c3b5a2cf", "IPY_MODEL_54811c02f756439693b4dab8457271b6" ], "layout": "IPY_MODEL_b03b0800c74741a4b221b472d210a5a3" } }, "fd9ce3a5f6b244a2aab6a0b4c3b5a2cf": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "PlayModel", "state": { "interval": 1000, "layout": "IPY_MODEL_52f3fd119ede4ef69cac3af9365f25f6", "max": 38, "style": "IPY_MODEL_d3316de7499e45e8a19e378c294187cf", "value": 16 } }, "ff02945c58294ac6b296ac7dbfde78a0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_0ab2a42cbc8740dba1fa5d7122588ac3", "IPY_MODEL_747edf0666ab4b6d9a4363d783755282" ], "layout": "IPY_MODEL_6c6e876da2e24a618237dd2f5f91923d" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 2 }