{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "In this demo, we will be exploring how world developmental indicators are related to a country’s early effort in COVID-19 response. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "

Visualizations of dataframes beyond simple tables

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To enable Lux, simply add `import lux` along with your Pandas import statement." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "import lux\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lux preserves the Pandas dataframe semantics -- which means that you can apply any command from Pandas's API to the dataframes in Lux and expect the same behavior. For example, we can load the [Happy Planet Index (HPI)](http://happyplanetindex.org/) dataset via standard Pandas `read_csv` command." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv(\"https://github.com/lux-org/lux-datasets/blob/master/data/hpi_cleaned.csv?raw=True\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can quickly get an overview of the dataframe, simply by print out the dataframe `df`. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the Pandas table view, we see that the dataframe contains country-level data on sustainability and well-being.\n", "By clicking on the Toggle button, you can now explore the data visually through Lux, you should see several tabs of visualizations recommended to you that includes scatterplots, bar charts, and maps. In Lux, we recommend visualizations that may be relevant or interesting to you across different [actions](https://lux-api.readthedocs.io/en/latest/source/getting_started/overview.html#visualizing-dataframes-with-recommendations), which are displayed as different tabs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By inspecting the `Correlation` tab, we learn that there is a negative correlation between `AvrgLifeExpectancy` and `Inequality`. In other words, countries with higher levels of inequality also have a lower average life expectancy. We can also look at other tabs, which show the Distribution of quantitative attributes and the Occurrence of categorical attributes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "

Steering analysis with intent

\n", "
\n", "\n", "Let's say that we want to investigate whether any country-level characteristics explain the observed negative correlation between inequality and life expectancy. Beyond the basic recommendations, you can further specify your analysis *intent*, i.e., the data attributes and values that you are interested in visualizing. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can do this by specifying our analysis intent to Lux via `df.intent`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.intent = [\"Inequality\",\"AvrgLifeExpectancy\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Upon printing the dataframe again, Lux leverages the analysis intent to steer the recommendations towards what the user might be interested in." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By looking at the colored scatterplots in the `Enhance` tab, we find that most G10 industrialized countries are on the upper left quadrant on the scatterplot (low inequality, high life expectancy). In the breakdown by Region, we observe that countries in Sub-Saharan Africa (yellow points) tend to be on the bottom right, with lower life expectancy and higher inequality." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ℹ️ Check out [this tutorial](https://lux-api.readthedocs.io/en/latest/source/guide/intent.html#) to learn more about how to specify intent in Lux." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "

Data Manipulation + Vis without changing a line of your Pandas code

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lux is designed to be tightly integrated with Pandas and can be used as-is, without modifying your existing Pandas code. This means that you can seamlessly transition from doing data cleaning and transformation to visualizing your dataframes with no effort. The goal of this section is largely to demonstrate how Lux can help you visualize your dataframe in a realistic scenario that involves lots of complex data cleaning and transformation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Continuing our analysis, we are now interested in how these country-level metrics related to a country's early COVID intervention strategy and response, based on the [COVID pandemic policy dataset](https://ourworldindata.org/grapher/covid-stringency-index) dataset." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "covid = pd.read_csv(\"https://github.com/lux-org/lux-datasets/blob/master/data/covid_cleaned.csv?raw=True\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now join the countries dataframe `df` with the filtered COVID dataframe: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = covid.merge(df,left_on=[\"Entity\",\"Code\"],right_on=[\"Country\",\"cca3\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 🤔 Some interesting findings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With the modified dataframe, we revisit the negative correlation that we observed previously by setting the intent as average life expectancy and inequality again. The result is similar to what we saw before, with one visualization showing the breakdown by `stringency_level`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.intent = [\"Inequality\",\"AvrgLifeExpectancy\"]\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see a strong separation showing how stricter countries (blue) corresponded to countries with higher life expectancy and lower levels of inequality. This visualization indicates that these countries could possibly have a more well-developed public health infrastructure that promoted the early pandemic response. However, we observe three outliers that seem to defy this trend. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When we filter to these dataframe records, we find that these countries correspond to [Afghanistan](https://www.who.int/news-room/feature-stories/detail/afghanistan-who-mission-reviews-covid-19-response), [Pakistan](https://www.who.int/news-room/feature-stories/detail/covid-19-in-pakistan-who-fighting-tirelessly-against-the-odds), and [Rwanda](https://www.npr.org/sections/goatsandsoda/2020/07/15/889802561/a-covid-19-success-story-in-rwanda-free-testing-robot-caregivers)—countries that were praised for their early pandemic response despite limited resources." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df[(df[\"Inequality\"]>0.35)&(df[\"stringency_level\"]==\"High\")]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "

Exporting visualization insight to edit and share

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To download this visualization insight and share with others, we can click on the visualization in the Lux view above and the button." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This exports the visualization from the widget to a `Vis` object. We can access the exported `Vis` object via the `exported` property and print it as code." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.exported" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(df.exported[0].to_code(\"altair\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can copy-and-paste the output Altair code into a separate cell. Then let's tweak the plotting code a bit before sharing this insight with our colleagues." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import altair as alt\n", "\n", "c = \"#e7298a\"\n", "chart = alt.Chart(df,title=\"Check out this cool insight!\").mark_circle().encode(\n", " x=alt.X('Inequality',scale=alt.Scale(domain=(0.04, 0.51)),type='quantitative', axis=alt.Axis(title='Inequality')),\n", " y=alt.Y('AvrgLifeExpectancy',scale=alt.Scale(domain=(48.9, 83.6)),type='quantitative', axis=alt.Axis(title='AvrgLifeExpectancy'))\n", ")\n", "highlight = df[(df[\"Inequality\"]>0.35)&(df[\"stringency_level\"]==\"High\")]\n", "\n", "hchart = alt.Chart(highlight).mark_point(color=c,size=50,shape=\"cross\").encode(\n", " x=alt.X('Inequality',scale=alt.Scale(domain=(0.04, 0.51)),type='quantitative', axis=alt.Axis(title='Inequality')),\n", " y=alt.Y('AvrgLifeExpectancy',scale=alt.Scale(domain=(48.9, 83.6)),type='quantitative', axis=alt.Axis(title='AvrgLifeExpectancy')),\n", ")\n", "\n", "text = alt.Chart(highlight).mark_text(color=c,dx=-35,dy=0,fontWeight=800).encode(\n", " x=alt.X('Inequality',scale=alt.Scale(domain=(0.04, 0.51)),type='quantitative', axis=alt.Axis(title='Inequality')),\n", " y=alt.Y('AvrgLifeExpectancy',scale=alt.Scale(domain=(48.9, 83.6)),type='quantitative', axis=alt.Axis(title='AvrgLifeExpectancy')),\n", " text=alt.Text('Country')\n", ")\n", "\n", "chart = chart.encode(color=alt.Color('stringency_level',type='nominal'))\n", "chart = chart.properties(width=160,height=150)\n", "\n", "(chart + hchart + text).configure_title(color=c)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ℹ️ Check out [this tutorial](https://lux-api.readthedocs.io/en/latest/source/guide/export.html) to learn more about exporting visualizations in Lux.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Try out Lux! " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get started, Lux can be installed through [PyPI](https://pypi.org/project/lux-api/). \n", "\n", "```bash\n", "pip install lux-api\n", "``` \n", "\n", "\n", "To use Lux in [Jupyter notebook](https://github.com/jupyter/notebook) or [VSCode](https://code.visualstudio.com/docs/python/jupyter-support), activate the notebook extension:\n", "\n", "```bash\n", "jupyter nbextension install --py luxwidget\n", "jupyter nbextension enable --py luxwidget\n", "```\n", "\n", "To use Lux in [Jupyter Lab](https://github.com/jupyterlab/jupyterlab), activate the lab extension:\n", "\n", "```bash\n", "jupyter labextension install @jupyter-widgets/jupyterlab-manager\n", "jupyter labextension install luxwidget\n", "```\n", "\n", "If you encounter issues with the installation, please refer to [this page](https://lux-api.readthedocs.io/en/latest/source/guide/FAQ.html#troubleshooting-tips) to troubleshoot the installation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### More information: \n", "\n", "- Follow us on [Twitter](https://twitter.com/lux_api) for discussion and updates.\n", "- Sign up for the early-user [mailing list](https://forms.gle/XKv3ejrshkCi3FJE6) to stay tuned for upcoming releases, updates, or user studies. \n", "- Visit [ReadTheDoc](https://lux-api.readthedocs.io/en/latest/) for more detailed documentation.\n", "- Check out our [notebook gallery](https://lux-api.readthedocs.io/en/latest/source/reference/gallery.html) for links to more demo, tutorial, and exercise on how to use Lux.\n", "- Report any bugs, issues, or requests through [Github Issues](https://github.com/lux-org/lux/issues). \n", "\n", "
Icons made by Freepik from www.flaticon.com
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.9.2" } }, "nbformat": 4, "nbformat_minor": 4 }