{ "cells": [ { "cell_type": "raw", "id": "d5e8b09c", "metadata": {}, "source": [ "---\n", "title: Animated Data Visualization with Mercury and Ipyvizzu\n", "description: Interactive animated visualizations using Mercury and Ipyvizzu\n", "show-code: False\n", "params:\n", " gender:\n", " input: select\n", " label: select the gender\n", " choices: [Male, Female]\n", " multi: False\n", "---" ] }, { "cell_type": "markdown", "id": "878b3da3", "metadata": {}, "source": [ "## Interactive animated visualization of Tips dataset\n", "### Choose the gender in the sidebar to get the different visualizations for corresponding gender" ] }, { "cell_type": "code", "execution_count": null, "id": "ea0d5dd6", "metadata": {}, "outputs": [], "source": [ "gender = 'Male'" ] }, { "cell_type": "code", "execution_count": null, "id": "ec20b668", "metadata": { "scrolled": true }, "outputs": [], "source": [ "import pandas as pd\n", "#import seaborn as sns\n", "from ipyvizzu import Chart, Data, Config, Style\n", "\n", "df = pd.read_csv('tips.csv')" ] }, { "cell_type": "code", "execution_count": null, "id": "97a176a6", "metadata": {}, "outputs": [], "source": [ "df['count'] = [1 for i in range(244)]" ] }, { "cell_type": "code", "execution_count": null, "id": "f3818143", "metadata": {}, "outputs": [], "source": [ "def draw(gender):\n", " data = Data()\n", " data.add_data_frame(df.loc[(df.sex==gender)])\n", " chart = Chart()\n", " chart.animate(data)\n", " chart.animate(Config({\"x\": [\"smoker\",'day'] ,\"y\": [\"total_bill\"] ,\"label\":['day','smoker', 'count'], \"color\": \"day\", \"title\": str(gender)+ \" smoker total bill based on days\"}))\n", " chart.animate(Config({\"y\": [\"smoker\",'day'] ,\"x\": [\"tip\"] ,\"label\":['day','smoker', 'count'], \"color\": \"day\", \"title\":str(gender)+\" tips based on days\"}), style={\"duration\":3, \"delay\": 0.5})\n", " #Next is a temporary state where the \"smoker\" series is kept on the x-axis so that Vizzu can animate nicely\n", " chart.animate(\n", " Config(\n", " {\n", " \"channels\": {\n", " \"x\": {\"set\": [\"total_bill\",\"smoker\"]},\n", " \"y\": {\"set\": [\"day\"]},\n", " \"color\": {\"set\": [\"day\"]},\n", " \"label\": {\"set\": None},\n", " },\n", " \"title\": str(gender)+\" total bill day wise\",\n", " \"coordSystem\": \"polar\",\n", " }\n", " ),\n", " Style(\n", " {\n", " \"plot\": {\n", " \"yAxis\": {\"color\": \"#ffffff00\", \"label\": {\"paddingRight\": 20}},\n", " \"xAxis\": {\n", " \"title\": {\"color\": \"#ffffff00\"},\n", " \"label\": {\"color\": \"#ffffff00\"},\n", " \"interlacing\": {\"color\": \"#ffffff00\"},\n", " },\n", " }\n", " }\n", " ),\n", " style={\"duration\":3,\n", " \"delay\": 0.5})\n", "#Here we simply remove the extra series from the x-axis - this will also result in the chart fading but since all markers stay at the same place this is not disturbing for the viewer. Also this is the time to show the values via the label scale.\n", " chart.animate(\n", " Config(\n", " {\n", " \"channels\": {\n", " \"x\": {\"set\": [\"total_bill\"]},\n", " \"label\": {\"set\": [\"total_bill\"]},\n", " },\n", " }\n", " ))\n", "\n", "#Once again a temporary state, where we add the \"time\" series to the x-axis. The viewer doesn't see any change but this will enable us to do the next animation nicely. Label has to be removed as the bars are being split now via the \"time\" values even though the viewer can't see that.\n", " chart.animate(\n", " Config(\n", " {\n", " \"channels\": {\n", " \"x\": {\"set\": [\"total_bill\",\"time\"]},\n", " \"label\": {\"set\": None},\n", " },\n", " }\n", " ),style={\"delay\": 1})\n", " \n", "#This is where the animation happens. We still keep the \"day\" series on the chart, even though we won't need them anymore. Again this is to make a nice animation and we'll remove this in the next stage.\n", " chart.animate(\n", " Config(\n", " {\n", " \"channels\": {\n", " \"x\": {\"set\": [\"tip\",\"day\"]},\n", " \"y\": {\"set\": [\"time\"]},\n", " \"color\": {\"set\": [\"time\"]},\n", " },\n", " \"title\": str(gender)+\" tips based on time\",\n", " }\n", " ),\n", " Style(\n", " {\n", " \"plot\": {\n", " \"marker\": {\"label\": {\"fontSize\": 14}},\n", " \"xAxis\": {\n", " \"title\": {\"color\": \"#ffffff00\"},\n", " \"label\": {\"color\": \"#ffffff00\"},\n", " \"ticks\": {\"color\": \"#ffffff00\"},\n", " \"interlacing\": {\"color\": \"#ffffff00\"},\n", " },\n", " \"yAxis\": {\n", " \"color\": \"#ffffff00\",\n", " \"title\": {\"color\": \"#ffffff00\"},\n", " \"label\": {\"color\": \"#ffffff00\"},\n", " },\n", " }\n", " }\n", " ),\n", " style={\"duration\":1,\n", " \"delay\": 0.5})\n", "\n", "\n", "#Lastly we remove the unnecessary \"day\" series and show what we want to show on the label scale. Please note that only those settings have to be expressed within the animate function that change within states. Otherwise, all other settings will stay the same.\n", " chart.animate(\n", " Config(\n", " {\n", " \"channels\": {\n", " \"x\": {\"set\": [\"tip\"]},\n", " \"label\": {\"set\": [\"time\",\"tip\"]},\n", " },\n", " }\n", " ))\n", " \n", " " ] }, { "cell_type": "code", "execution_count": null, "id": "3ade80c7", "metadata": {}, "outputs": [], "source": [ "draw(gender)" ] } ], "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.8.13" } }, "nbformat": 4, "nbformat_minor": 5 }