{ "cells": [ { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2020-09-01T02:58:28.765090Z", "start_time": "2020-09-01T02:58:28.761362Z" } }, "source": [ "(content:plotting_maps)=\n", "# Plotting Maps\n", "\n", "In this notebook, we will finally plot some visualizations based on [the post-processed collection previously created](content:post_process_collection). For that, we will use the python package `folium` (please install it with `pip install folium`)." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:00.719523Z", "start_time": "2021-02-24T11:36:00.714696Z" } }, "outputs": [], "source": [ "import folium\n", "import pandas as pd\n", "import numpy as np\n", "import base64\n", "import io\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This simple map that we are going to plot will need two files:\n", "1. [The post-processed collection (processed_top5_cities.csv)](content:post_process_collection)\n", "2. The Geojson/Shapefiles/KML/Lat-long for locations. This information was included in the [original data (worldcities_fb_keys.csv)](content:json_creation), but could also be obtained by querying Facebook for [KMLs](content:listing_all_cities_states_in_a_country_region) or by other Websites, such as [GADM](https://gadm.org/data.html)." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:18.021530Z", "start_time": "2021-02-24T11:36:17.989150Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
KeyNameRegionFullLocationboth_18-40_2Gboth_18-40_3Gboth_18-40_4Gboth_18-40_AllDevicesboth_18-40_Wifiboth_18-_2G...populationidfb_querynamekeyregionregion_idcountry_namecountry_codetype
02880782Minato-kuTokyoMinato-ku, Tokyo, JP10001000840064000340001000...35676000.01392685764TokyoMinato-ku2880782Tokyo1922JapanJPcity
12490299New YorkNew YorkNew York, New York, US10004900520000330000016000001000...19354922.01840034016New YorkNew York2490299New York3875United StatesUScity
22673660Mexico CityDistrito FederalMexico City, Distrito Federal, MX12001600001000000760000048000001700...19028000.01484247881Mexico CityMexico City2673660Distrito Federal2513MexicoMXcity
31035921MumbaiMaharashtraMumbai, Maharashtra, IN110004600053000009000000170000014000...18978000.01356226629MumbaiMumbai1035921Maharashtra1735IndiaINcity
4269969São PauloSão Paulo (state)São Paulo, São Paulo (state), BR100045000510000580000037000002000...18845000.01076532519São PauloSão Paulo269969São Paulo (state)460BrazilBRcity
\n", "

5 rows × 83 columns

\n", "
" ], "text/plain": [ " Key Name Region FullLocation \\\n", "0 2880782 Minato-ku Tokyo Minato-ku, Tokyo, JP \n", "1 2490299 New York New York New York, New York, US \n", "2 2673660 Mexico City Distrito Federal Mexico City, Distrito Federal, MX \n", "3 1035921 Mumbai Maharashtra Mumbai, Maharashtra, IN \n", "4 269969 São Paulo São Paulo (state) São Paulo, São Paulo (state), BR \n", "\n", " both_18-40_2G both_18-40_3G both_18-40_4G both_18-40_AllDevices \\\n", "0 1000 1000 8400 64000 \n", "1 1000 4900 520000 3300000 \n", "2 1200 160000 1000000 7600000 \n", "3 11000 46000 5300000 9000000 \n", "4 1000 45000 510000 5800000 \n", "\n", " both_18-40_Wifi both_18-_2G ... population id fb_query \\\n", "0 34000 1000 ... 35676000.0 1392685764 Tokyo \n", "1 1600000 1000 ... 19354922.0 1840034016 New York \n", "2 4800000 1700 ... 19028000.0 1484247881 Mexico City \n", "3 1700000 14000 ... 18978000.0 1356226629 Mumbai \n", "4 3700000 2000 ... 18845000.0 1076532519 São Paulo \n", "\n", " name key region region_id country_name \\\n", "0 Minato-ku 2880782 Tokyo 1922 Japan \n", "1 New York 2490299 New York 3875 United States \n", "2 Mexico City 2673660 Distrito Federal 2513 Mexico \n", "3 Mumbai 1035921 Maharashtra 1735 India \n", "4 São Paulo 269969 São Paulo (state) 460 Brazil \n", "\n", " country_code type \n", "0 JP city \n", "1 US city \n", "2 MX city \n", "3 IN city \n", "4 BR city \n", "\n", "[5 rows x 83 columns]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_fb = pd.read_csv(\"processed_top5_cities.csv\")\n", "df_loc = pd.read_csv(\"worldcities_fb_keys.csv\")\n", "\n", "df = pd.merge(df_fb, df_loc, left_on=\"Key\", right_on=\"key\")\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A Basic Map" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Folium is an amazing Python tool that directly uses [leaflet](https://leafletjs.com/) JavaScritp library for iteractive maps. We recommend the reader to take a look at the [latest folium documentation](https://python-visualization.github.io/folium/quickstart.html) and [the various examples of how to use this library](https://nbviewer.jupyter.org/github/python-visualization/folium/tree/master/examples/).\n", "\n", "A simple map for our use case is based on the following code that explores the `tooltip` and `popup` concepts on top of the markers of each city." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:21.328736Z", "start_time": "2021-02-24T11:36:21.298326Z" } }, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = folium.Map(location=[0, 0], zoom_start=2, tiles=\"openstreetmap\", control_scale = True)\n", "\n", "for idx, row in df.iterrows():\n", " tooltip = 'City name: %s!' % (row[\"name\"])\n", " html = \"

%s

Total FB pop: %d\" % (row[\"name\"], row[\"both_18-_AllDevices\"])\n", " popup = folium.Popup(html, max_width=450, min_width=450)\n", "\n", " folium.Marker([row[\"lat\"], row[\"lng\"]], popup=popup, tooltip=tooltip).add_to(m)\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When any of the locations is clicked, a pop up showing the city name and the total Facebook audience is shown.\n", "This number is based on the column **both_18-_AllDevices**, and as [explaned before](content:post_process_collection), it represents both male and female audience aged at least 18 years old and using any network to connect to Facebook. \n", "\n", "```{warning}\n", "Note that the correct column name will depend on the criteria used in the collection!\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Improving the Basic Map" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2020-09-01T03:01:11.277294Z", "start_time": "2020-09-01T03:01:11.271663Z" } }, "source": [ "Next we will define a few functions to be able to plot a much more interesting map.\n", "The functions ``getPie`` and ``getPyramid`` can be used in other contexts as well.\n", "The parameter `get_encoded` is decide if these functions should return an image HTML encoded or not. For the maps, we will use `get_encoded=True`." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:23.242631Z", "start_time": "2021-02-24T11:36:23.236069Z" } }, "outputs": [], "source": [ "def getPie(labels, sizes, explode=None, title=None, get_encoded=True):\n", " \n", " # Pie chart, where the slices will be ordered and plotted counter-clockwise:\n", " # Examples:\n", " # labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'\n", " # sizes = [15, 30, 45, 10]\n", " # explode = (0, 0.1, 0, 0) # only \"explode\" the 2nd slice (i.e. 'Hogs')\n", "\n", " \n", " def label_formant(pct, allvals):\n", " absolute = int(pct/100.*np.sum(allvals))\n", " return \"{:.1f}%\\n({:,d})\".format(pct, absolute)\n", " \n", " # TODO: make it like a doughout\n", " # https://matplotlib.org/3.1.1/gallery/pie_and_polar_charts/pie_and_donut_labels.html\n", " \n", " fig1, ax1 = plt.subplots(figsize=(2,2))\n", " ax1.pie(sizes, explode=explode, labels=labels,\n", " autopct=lambda pct: label_formant(pct, sizes),\n", " shadow=True, startangle=90, counterclock=False, \n", " wedgeprops = {'linewidth' : 2, 'edgecolor': \"black\", }\n", " )\n", " \n", " if title:\n", " ax1.set_title(title)\n", " ax1.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.\n", "\n", " if get_encoded:\n", " img_buffer = io.BytesIO()\n", " plt.savefig(img_buffer, format='png', transparent=True, bbox_inches=\"tight\")\n", " img_buffer.seek(0)\n", " plt.close()\n", " \n", " return base64.b64encode(img_buffer.getvalue()).decode('UTF-8')\n", " \n", " else:\n", " return plt\n", " " ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:24.008666Z", "start_time": "2021-02-24T11:36:23.907173Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "getPie([\"Frogs\", \"Hogs\", \"Dogs\", \"Logs\"], [15, 30, 45, 10], (0, 0.1, 0, 0), get_encoded=False)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:24.558113Z", "start_time": "2021-02-24T11:36:24.458292Z" } }, "outputs": [ { "data": { "text/plain": [ "'iVBORw0KGgoAAAANSUhEUgAAAKgAAAB9CAYAAAA2uCgoAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAvn0lEQVR4nO2deXhcVfnHP++9s2/Z0yRN2zRd2Rvaskhlt2UTWVREVASURVARRNCfK+4ii4IIguygILuIKFCgVChF6L6mTZfsezJZZrv3nt8fd5KmTdomadqZYD7Pkycz95577rkz3znL+77nHFFKMcYY6YqW6gKMMcaeGBPoGGnNmEDHSGvGBDpGWjMm0DHSmjGBjpHWjBqBikhnqsswxoFn1Ah0jP9NRrVARWSWiCwRkZUi8pyIZCWPz00ee1dEbhGR1cnjh4jIUhFZnjw/LbVPMMbeGNUCBR4BblRKHQ6sAn6UPP4gcKVS6ljA7JP+SuB3SqlZwByg6gCWdZ8QETP5w+r5K0l1mQ4EjlQXYLiISAaQqZR6K3noYeBvIpIJBJVS7ySPPwGclXz9LvB/IlIMPKuUKj+QZd5HIskfVj9ERABRSlkHtkj7n9Fegw6E7O6EUuoJ4GwgAvxLRE4ekRvaAjmgiEiJiKwTkbuBD4EJPd0ZEVklIhck02kicreIrBGRl0TkZRH5dPLcr0RkbbK789sD/QyDYdTWoEqpdhFpFZGPK6XeBr4IvKWUahWRDhE5Rim1BPhczzUiUgpUKKV+n3x9OLBwoPyTossDDkr+zUz+nwr4ARcQxP4MEyISAbqBSmB78m9b8v86YIPat8gcr4gsT77eAnwLmAFcopT6moicD8wCjgBygfdFZBFwHFACHAbkJ8vygIhkA+cCM5VSKtnypB2jSaA+EenbZ7wNuBi4R0R8QAVwSfLcZcB9ItIFvAm0J49fAHxBRBJAHXBzT2Yi4gZOwO4OzMYWY9Ygy+ZM/oWAAmDuAGkaRWQx'" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "getPie([\"Frogs\", \"Hogs\", \"Dogs\", \"Logs\"], [15, 30, 45, 10], (0, 0.1, 0, 0), get_encoded=True)[:1000]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:36:25.054350Z", "start_time": "2021-02-24T11:36:25.047456Z" } }, "outputs": [], "source": [ "def getPyramid(y, labels, data_left, data_right, normalized=False, get_buffer=True):\n", " \n", " # E.g.:\n", " # y = [0-18, 19-25, 26+]\n", " # labels = [female, male]\n", " # data_left = [1000, 2000, 3000]\n", " # data_right = [2000, 5000, 1000]\n", " \n", " data_left = np.array(data_left)\n", " data_right = np.array(data_right)\n", " \n", " if normalized:\n", " data_left = data_left / data_left.sum()\n", " data_right = data_right / data_right.sum()\n", " \n", " assert data_left.shape == data_right.shape\n", " N = range(0, data_left.shape[0])\n", " \n", " fig1, ax1 = plt.subplots(figsize=(2,2))\n", " \n", " ax1.barh(N, -data_left, label=labels[0])\n", " ax1.barh(N, data_right, label=labels[1])\n", " \n", " ax1.set(yticks=N, yticklabels=y)\n", " \n", " ax1.spines['right'].set_visible(False)\n", " ax1.spines['top'].set_visible(True)\n", " ax1.spines[\"top\"]._linewidth = 2\n", " \n", " ax1.spines['left'].set_visible(False)\n", " ax1.spines['bottom'].set_visible(True)\n", " ax1.spines['bottom']._linewidth = 2\n", " \n", " ax1.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15),\n", " fancybox=True, shadow=True, ncol=5)\n", "\n", " if get_buffer:\n", " img_buffer = io.BytesIO()\n", " plt.savefig(img_buffer, format='png', transparent=True, bbox_inches=\"tight\")\n", " img_buffer.seek(0)\n", " plt.close()\n", " return base64.b64encode(img_buffer.getvalue()).decode('UTF-8')\n", " \n", " else:\n", " return plt\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function ``getHTML`` will render an HTML including images generated by these other functions." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:39:08.471720Z", "start_time": "2021-02-24T11:39:08.464370Z" } }, "outputs": [], "source": [ "def getHTML(row):\n", " \n", " total_pop = float(row['both_18-_AllDevices'])\n", " \n", " pie_gender = getPie([\"Male\", \"Female\"], [row[\"male_18-_AllDevices\"], row[\"female_18-_AllDevices\"]])\n", " pie_connectivity = getPie([\"Wifi\", \"2G\", \"3G\", \"4G\"], [row[\"both_18-_Wifi\"], row[\"both_18-_2G\"], \n", " row[\"both_18-_3G\"], row[\"both_18-_4G\"], ])\n", " pie_connectivity_male = getPie([\"Wifi\", \"2G\", \"3G\", \"4G\"], [row[\"male_18-_Wifi\"], row[\"male_18-_2G\"],\n", " row[\"male_18-_3G\"], row[\"male_18-_4G\"]], \n", " title=\"Connectivity (Male)\")\n", " pie_connectivity_female = getPie([\"Wifi\", \"2G\", \"3G\", \"4G\"], [row[\"female_18-_Wifi\"], row[\"female_18-_2G\"],\n", " row[\"female_18-_3G\"], row[\"female_18-_4G\"],], \n", " title=\"Connectivity (Female)\")\n", " \n", " pie_age = getPie([\"18-40\", \"41-54\", \"55+\"], [row[\"both_18-40_AllDevices\"], row[\"both_41-54_AllDevices\"],\n", " row[\"both_55-_AllDevices\"]])\n", " \n", " pyramid_age = getPyramid([\"18-40\", \"41-54\", \"55+\"], [\"female\", \"male\"],\n", " [row[\"female_18-40_AllDevices\"], row[\"female_41-54_AllDevices\"], row[\"female_55-_AllDevices\"]],\n", " [row[\"male_18-40_AllDevices\"], row[\"male_41-54_AllDevices\"], row[\"male_55-_AllDevices\"]]\n", " )\n", " \n", " pyramid_age_perc = getPyramid([\"18-40\", \"41-54\", \"55+\"], [\"female\", \"male\"],\n", " [row[\"female_18-40_AllDevices\"], row[\"female_41-54_AllDevices\"], row[\"female_55-_AllDevices\"]],\n", " [row[\"male_18-40_AllDevices\"], row[\"male_41-54_AllDevices\"], row[\"male_55-_AllDevices\"]],\n", " normalized=True)\n", "\n", " \n", " \n", " html = \"\"\"\n", "

Location: {name} ({lat:.1f}, {lng:.1f})


\n", "
Total Population: {total_pop:,}
\n", " \n", " \n", "
Gender Distribution:
\n", "
\n", " \n", "
Age Distribution
\n", "
\n", " \n", "
Age Distribution per Gender
\n", "
\n", " \n", " \n", "
\n", " \n", " \n", " \n", "
Connectivity <\\h5>\n", "
\n", " \n", "
Connectivity per Gender <\\h5>\n", "
\n", " \n", " \n", " \n", " \"\"\".format(name=row[\"name\"], \n", " lat=float(row[\"lat\"]), lng=float(row[\"lng\"]), \n", " total_pop=total_pop,\n", " pie_gender=pie_gender,\n", " pie_age=pie_age,\n", " pyramid_age=pyramid_age,\n", " pyramid_age_perc=pyramid_age_perc,\n", " pie_connectivity=pie_connectivity,\n", " pie_connectivity_male=pie_connectivity_male,\n", " pie_connectivity_female=pie_connectivity_female,\n", " \n", " )\n", "\n", " # TRY TO FORMAT WITH https://docs.python.org/3/library/string.html#format-specification-mini-language\n", " return html\n" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "ExecuteTime": { "end_time": "2021-02-24T11:39:44.070326Z", "start_time": "2021-02-24T11:39:41.201818Z" } }, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# There are many options for tile. Here we are using the first one, openstreetmaps\n", "tile_options = ['openstreetmap', 'cartodbpositron', 'Mapbox Bright', \n", " 'Stamen Terrain', 'Stamen Toner', 'Stamen Watercolor',\n", " 'Mapbox Control Room', 'CartoDB dark_matter', ]\n", "\n", "tiles = tile_options[0]\n", "\n", "m = folium.Map(location=[0, 0], zoom_start=2, tiles=tiles, control_scale = True)\n", "\n", "\n", "for idx, row in df.iterrows():\n", " html = getHTML(row)\n", " popup = folium.Popup(html, max_width=450, min_width=450)\n", "\n", " tooltip = '%s!' % (row[\"name\"])\n", "\n", " folium.Marker([row[\"lat\"], row[\"lng\"]], popup=popup, tooltip=tooltip).add_to(m)\n", "\n", "m" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2020-09-23T04:22:14.183755Z", "start_time": "2020-09-23T04:22:13.483670Z" } }, "outputs": [], "source": [ "# It is much easier to see the outcome of this notebook as a HTML file.\n", "m.save('connetivity_top5_cities.html')" ] } ], "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.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }