{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualization\n", "\n", "### Introduction\n", "\n", "As a data scientist, you likely work through a data exploration processes on nearly every project. Exploratory data analysis can entail many things from finding relevant data and cleaning it to running analysis and building models. The ability to visually analyze and interact with data is key during the exploratory process and the final presentation of insights.\n", "\n", "With that in mind, this guide introduces the basic building blocks for creating web-based, dynamic, and interactive map visualizations inside of a Jupyter Notebook with CARTOframes.\n", "\n", "In this guide you are introduced to the Map and Layer classes, how to explore data with Widgets and Popups, how to use visualization styles to quickly symbolize thematic attributes, and options for creating maps to share your findings.\n", "\n", "### Data\n", "\n", "This guide uses two datasets: a point dataset of simulated Starbucks locations in Brooklyn, New York and 15 minute walk time polygons (isochrones) around each store augmented with demographic variables from CARTO's [Data Observatory](developers/cartoframes/guides/Data-discovery/). To follow along, you can get the [point dataset here](http://libs.cartocdn.com/cartoframes/files/starbucks_brooklyn_geocoded.csv) and the [polygon dataset here](http://libs.cartocdn.com/cartoframes/files/starbucks_brooklyn_iso_enriched.csv).\n", "\n", "As a first step, load both datasets as [pandas.DataFrame](https://pandas.pydata.org/pandas-docs/stable/getting_started/dsintro.html#dataframe) into the notebook:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from pandas import read_csv\n", "from geopandas import GeoDataFrame\n", "from cartoframes.utils import decode_geometry\n", "\n", "# store point locations\n", "stores_df = read_csv('http://libs.cartocdn.com/cartoframes/files/starbucks_brooklyn_geocoded.csv')\n", "stores_gdf = GeoDataFrame(stores_df, geometry=decode_geometry(stores_df['the_geom']))\n", "\n", "# 15 minute walk time polygons\n", "iso_df = read_csv('http://libs.cartocdn.com/cartoframes/files/starbucks_brooklyn_iso_enriched.csv')\n", "iso_gdf = GeoDataFrame(iso_df, geometry=decode_geometry(iso_df['the_geom']))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Add Layers to a Map\n", "\n", "Next, import the Map and Layer classes from the [Viz namespace](/developers/cartoframes/reference/#heading-Viz) to visualize the two datasets. The resulting map draws each dataset with default symbology on top of CARTO's Positron basemap with the zoom and center set to the extent of both datasets:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " None\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", " Static map image\n", " \n", " \n", "
\n", "
\n", "
\n", " \n", " \n", "
\n", "
\n", "
\n", "\n", " \n", "\n", "
\n", "
\n", " :\n", "
\n", " \n", " \n", "
\n", "
\n", "\n", "
\n", " StackTrace\n", "
    \n", "
    \n", "
    \n", "\n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import Map, Layer\n", "\n", "Map([\n", " Layer(iso_gdf),\n", " Layer(stores_gdf)\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> To learn more about basemap options, visit the Map Configuration [Examples](/developers/cartoframes/examples/) section of the CARTOframes Developer Center" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Explore Attributes\n", "\n", "Before going further, take a look at the attributes in each dataset to get a sense of the information available to visualize and interact with.\n", "\n", "First, explore the store location attributes. In this dataset you will use the fields:\n", "* `id_store` that is a unique identifier for each of the locations\n", "* `revenue` which provides the information about how much a particular store earned in the year 2018" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "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", "
    the_geomcartodb_idfield_1nameaddressrevenueid_storegeometry
    00101000020E61000005EA27A6B607D52C01956F146E655...10Franklin Ave & Eastern Pkwy341 Eastern Pkwy,Brooklyn, NY 112381321040.772APOINT (-73.95901 40.67109)
    10101000020E6100000B610E4A0847D52C0B532E197FA49...21607 Brighton Beach Ave607 Brighton Beach Avenue,Brooklyn, NY 112351268080.418BPOINT (-73.96122 40.57796)
    20101000020E6100000E5B8533A587F52C05726FC523F4F...3265th St & 18th Ave6423 18th Avenue,Brooklyn, NY 112041248133.699CPOINT (-73.98976 40.61912)
    \n", "
    " ], "text/plain": [ " the_geom cartodb_id field_1 \\\n", "0 0101000020E61000005EA27A6B607D52C01956F146E655... 1 0 \n", "1 0101000020E6100000B610E4A0847D52C0B532E197FA49... 2 1 \n", "2 0101000020E6100000E5B8533A587F52C05726FC523F4F... 3 2 \n", "\n", " name address \\\n", "0 Franklin Ave & Eastern Pkwy 341 Eastern Pkwy,Brooklyn, NY 11238 \n", "1 607 Brighton Beach Ave 607 Brighton Beach Avenue,Brooklyn, NY 11235 \n", "2 65th St & 18th Ave 6423 18th Avenue,Brooklyn, NY 11204 \n", "\n", " revenue id_store geometry \n", "0 1321040.772 A POINT (-73.95901 40.67109) \n", "1 1268080.418 B POINT (-73.96122 40.57796) \n", "2 1248133.699 C POINT (-73.98976 40.61912) " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stores_gdf.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the isochrone Layer, you will use the demographic attributes:\n", "\n", "* `popcy` which counts the total population in each area\n", "* `inccymedhh` that is the median household income in each area\n", "* `lbfcyempl` counts the employed population\n", "* `educybach` counts the number of people with a bachelor's degree\n", "* `id_store` which matches the unique id in the store points" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "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", "
    the_geomcartodb_idpopcydata_rangerange_labellbfcyempleducybachinccymedhhid_storegeometry
    00106000020E61000000100000001030000000100000033...31311.66700590015 min.568.006658151.68221748475.834346CMULTIPOLYGON (((-73.99082 40.62694, -73.99170 ...
    10106000020E61000000100000001030000000100000033...72215.53929090015 min.1181.265882313.73981035125.870621GMULTIPOLYGON (((-73.87101 40.66114, -73.87166 ...
    20106000020E61000000100000001030000000100000033...91683.22918690015 min.1012.737753449.87100587079.135091IMULTIPOLYGON (((-73.98467 40.70054, -73.98658 ...
    \n", "
    " ], "text/plain": [ " the_geom cartodb_id popcy \\\n", "0 0106000020E61000000100000001030000000100000033... 3 1311.667005 \n", "1 0106000020E61000000100000001030000000100000033... 7 2215.539290 \n", "2 0106000020E61000000100000001030000000100000033... 9 1683.229186 \n", "\n", " data_range range_label lbfcyempl educybach inccymedhh id_store \\\n", "0 900 15 min. 568.006658 151.682217 48475.834346 C \n", "1 900 15 min. 1181.265882 313.739810 35125.870621 G \n", "2 900 15 min. 1012.737753 449.871005 87079.135091 I \n", "\n", " geometry \n", "0 MULTIPOLYGON (((-73.99082 40.62694, -73.99170 ... \n", "1 MULTIPOLYGON (((-73.87101 40.66114, -73.87166 ... \n", "2 MULTIPOLYGON (((-73.98467 40.70054, -73.98658 ... " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iso_gdf.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visual and Interactive Data Exploration\n", "\n", "Now that you've taken a first look at the fields in the data and done a basic visualization, let's look at how you can use the map as a tool for visual and interactive exploration to better understand the relationship between a store's annual revenue and the surrounding area's demographic characteristics.\n", "\n", "#### Add Widgets\n", "\n", "As seen in the table summaries above, there are a variety of demographic attributes in the isochrone Layer that would be helpful to better understand the characteristics around each store.\n", "\n", "To make this information available while exploring each location on the map, you can add each attribute as a [Widget](developers/cartoframes/reference/#heading-Widgets). For this case specifically, you will use [Formula Widgets](/developers/cartoframes/examples/#example-formula-widget) to summarize the demographic variables and a [Category Widget](/developers/cartoframes/examples/#example-category-widget) on the categorical attribute of `id_store`.\n", "\n", "To add Widgets, you first need to import the types that you want to use and then, inside of the `iso_gdf` Layer add one widget for each attribute of interest. The Formula Widget accepts different types of aggregations. For this map, you will aggregate each demographic variable using `sum` so the totals update as you zoom, pan and interact with the map. You will also label each Widget appropriately using the `title` parameter." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " None\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", " Static map image\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", " StackTrace\n", "
      \n", "
      \n", "
      \n", "\n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import formula_widget, category_widget\n", "\n", "Map([\n", " Layer(\n", " iso_gdf,\n", " widgets=[\n", " formula_widget(\n", " 'popcy',\n", " 'sum',\n", " title='Total Population Served'\n", " ),\n", " formula_widget(\n", " 'inccymedhh',\n", " 'sum',\n", " title='Median Income ($)'\n", " ),\n", " formula_widget(\n", " 'lbfcyempl',\n", " 'sum',\n", " title='Employed Population',\n", " ),\n", " formula_widget(\n", " 'educybach',\n", " 'sum',\n", " title='Number of People with Bachelor Degree',\n", " ),\n", " category_widget(\n", " 'id_store',\n", " title='Store ID'\n", " )\n", " ]\n", " ),\n", " Layer(\n", " stores_gdf\n", " )\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At this point, take a few minutes to explore the map to see how the Widget values update. For example, select a Store ID from the Category Widget to summarize the demographics for a particular store. Alternatively, zoom and pan the map to get summary statistics for the features in the current map view.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Add Popups\n", "\n", "In order to aid this map-based exploration, import the [Popup](developers/cartoframes/examples/#example-popup-on-hover) class and use the hover option on the `iso_gdf` Layer to be able to quickly hover over stores and get their ID:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " None\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", " Static map image\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", " StackTrace\n", "
        \n", "
        \n", "
        \n", "\n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import popup_element\n", "\n", "Map([\n", " Layer(\n", " iso_gdf,\n", " widgets=[\n", " formula_widget(\n", " 'popcy',\n", " 'sum',\n", " title='Total Population Served'\n", " ),\n", " formula_widget(\n", " 'inccymedhh',\n", " 'sum',\n", " title='Median Income ($)'\n", " ),\n", " formula_widget(\n", " 'lbfcyempl',\n", " 'sum',\n", " title='Employed Population',\n", " ),\n", " formula_widget(\n", " 'educybach',\n", " 'sum',\n", " title='Number of People with Bachelor Degree',\n", " ),\n", " category_widget(\n", " 'id_store',\n", " title='Store ID'\n", " )\n", " ],\n", " popup_hover=[\n", " popup_element('id_store', 'Store ID')\n", " ]\n", " ),\n", " Layer(\n", " stores_gdf\n", " )\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, as you explore the map and summarize demographics, it is much easier to relate the summarized values to a unique store ID." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Symbolize Store Points\n", "\n", "At this point, you have some really useful information available on the map but only coming from the isochrone Layer. Sizing the store points by the attribute `revenue` will provide a way to visually locate which stores are performing better than others. A quick way to visualize numeric or categorical attributes during the data exploration process is to take advantage of [visualization styles](/developers/cartoframes/reference/#heading-Helpers).\n", "\n", "To size the store points proportionate to their revenue, you'll use the [`size_continuous_style`](/developers/cartoframes/examples/#example-size-continuous-style):" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " None\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", " Static map image\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", " StackTrace\n", "
          \n", "
          \n", "
          \n", "\n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import size_continuous_style\n", "\n", "Map([\n", " Layer(\n", " iso_gdf,\n", " widgets=[\n", " formula_widget(\n", " 'popcy',\n", " 'sum',\n", " title='Total Population Served'\n", " ),\n", " formula_widget(\n", " 'inccymedhh',\n", " 'sum',\n", " title='Median Income ($)'\n", " ),\n", " formula_widget(\n", " 'lbfcyempl',\n", " 'sum',\n", " title='Employed Population',\n", " ),\n", " formula_widget(\n", " 'educybach',\n", " 'sum',\n", " title='Number of People with Bachelor Degree',\n", " ),\n", " category_widget(\n", " 'id_store',\n", " title='Store ID'\n", " )\n", " ],\n", " popup_hover=[\n", " popup_element('id_store', title='Store ID')\n", " ]\n", " ),\n", " Layer(\n", " stores_gdf,\n", " size_continuous_style('revenue')\n", " )\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now you have a proportional symbol map where points are sized by revenue. You will also notice that an appropriate legend has been added to the map and when you hover over the points, you will see each store's revenue value.\n", "\n", "Next, let's take a look at how to modify some of the defaults.\n", "\n", "Every Visualization Layer has a set of parameters available to customize the defaults to better suit a given map. A quick way to see which parameters are available for customization in the `size_continuous_style`, is to run `help(size_continuous_style)` in a notebook cell.\n", "\n", "Let's make a few adjustments to make it easier to distinguish and locate the highest and lowest performing stores:\n", "\n", "* The continuous point size reads between a minimum and maximum range of symbol sizes. Since the smallest revenue value on this map is hard to see, set `size_range=[10,50]`\n", "* By default both the Legend and Popup titles are set to the attribute being visualized. To give them more descriptive titles, set `title=Annual Revenue ($)`\n", "* In order to see and interact with the distribution of revenue values, you can also add a Histogram Widget (turned off by default) by setting `default_widget=True`" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " None\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", " Static map image\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", " StackTrace\n", "
            \n", "
            \n", "
            \n", "\n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import size_continuous_style\n", "\n", "Map([\n", " Layer(\n", " iso_gdf,\n", " widgets=[\n", " formula_widget(\n", " 'popcy',\n", " 'sum',\n", " title='Total Population Served'\n", " ),\n", " formula_widget(\n", " 'inccymedhh',\n", " 'sum',\n", " title='Median Income ($)'\n", " ),\n", " formula_widget(\n", " 'lbfcyempl',\n", " 'sum',\n", " title='Employed Population',\n", " ),\n", " formula_widget(\n", " 'educybach',\n", " 'sum',\n", " title='Number of People with Bachelor Degree',\n", " ),\n", " category_widget(\n", " 'id_store',\n", " title='Store ID'\n", " )\n", " ],\n", " popup_hover=[\n", " popup_element('id_store', 'Store ID')\n", " ]\n", " ),\n", " Layer(\n", " stores_gdf,\n", " size_continuous_style(\n", " 'revenue',\n", " size_range=[10,50]\n", " ),\n", " title='Annual Revenue ($)',\n", " default_widget=True\n", " )\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now you have a map to visually and interactively explore the relationship between revenue and demographic variables for each store:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Insights\n", "\n", "The map above provides a way to explore the data both visually and interactively in different ways:\n", "\n", "* you can almost instantaneously locate higher and lower performing stores based on the symbol sizes\n", "* you can zoom in on any store to summarize demographic characteristics\n", "* you can quickly find out the store ID by hovering on it\n", "* you can select a range of revenues from the Histogram Widget and have the map update to only display those stores\n", "* you can use the Store ID Category Widget to isolate a particular store and summarize values\n", "\n", "Use the map to see if you can find the highest and lowest performing stores and summarize the demographic characteristics of each one!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Present Insights\n", "\n", "Now that you have gained insight into the relationship between revenue and demographics, let's say that the most influential factor of how well a store performed was median income and you want to create a map to show that particular relationship.\n", "\n", "To show this, the map below uses another Visualization Layer, this time the [`color_bins_style`](/developers/cartoframes/examples/#example-color-bins-style) to color each isochrone according to the range of median household income it falls within. Additionally, the `size_continuous_style` used in the previous map has been further customized to account for the new thematic median income style, and the store points have been added again as a third Layer to show their location and ID on hover. The map also has a custom [viewport](https://carto.com/developers/cartoframes/examples/#example-set-custom-viewport) set to center it on the highest performing (A) and lowest performing (J) stores that have similar median income values." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " None\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", " Static map image\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", " Source: US Census Bureau\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", " StackTrace\n", "
              \n", "
              \n", "
              \n", "\n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import Map, Layer, color_bins_style, size_continuous_style, default_legend\n", "\n", "Map([\n", " Layer(\n", " iso_gdf,\n", " style=color_bins_style(\n", " 'inccymedhh',\n", " bins=7,\n", " palette='pinkyl',\n", " opacity=0.8,\n", " stroke_width=0\n", " ),\n", " legends=default_legend(title='Median Household Income ($)', footer='Source: US Census Bureau')\n", " ),\n", " Layer(\n", " stores_gdf,\n", " style=size_continuous_style(\n", " 'revenue',\n", " size_range=[10,50],\n", " range_max=1000000,\n", " opacity=0,\n", " stroke_color='turquoise',\n", " stroke_width=2\n", " ),\n", " legends=default_legend(title='Legend Title')\n", " ),\n", " Layer(\n", " stores_gdf,\n", " popup_hover=[\n", " popup_element('id_store', title='Store ID')\n", " ]\n", " )\n", "], viewport={'zoom': 12, 'lat': 40.644417, 'lng': -73.934710})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Compare Variables with a Layout\n", "\n", "If you want to compare store revenue with multiple demographic variables, you can create a [Layout](https://carto.com/developers/cartoframes/examples/#example-custom-layout) with multiple maps.\n", "\n", "In the example below, one map symbolizes annual revenue and the other three maps symbolize three demographic variables that use the same color palette where yellow is low and red is high. Each map has a title to label which attribute is being mapped." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " CARTOframes\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", " "Static\n", " \n", "
              \n", "
              \n", "
              \n", " \n", "\n", "
              \n", "
              \n", "
              \n", " \n", " \n", " \n", " \n", " \n", " \n", "
              \n", " \n", "\n", "
              \n", " "Static\n", " \n", "
              \n", "
              \n", "
              \n", " \n", "\n", "
              \n", "
              \n", "
              \n", " \n", "
              \n", " \n", "
              \n", " \n", " \n", " \n", " \n", " \n", " \n", "
              \n", " \n", "\n", "
              \n", " "Static\n", " \n", "
              \n", "
              \n", "
              \n", " \n", "\n", "
              \n", "
              \n", "
              \n", " \n", " \n", " \n", " \n", " \n", " \n", "
              \n", " \n", "\n", "
              \n", " "Static\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", " StackTrace\n", "
                \n", "
                \n", "
                \n", "\n", "\n", "\n", "\n", "\">\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from cartoframes.viz import Layout\n", "\n", "Layout([\n", " Map([\n", " Layer(\n", " stores_gdf,\n", " style=size_continuous_style(\n", " 'revenue',\n", " size_range=[10,50],\n", " range_max=1000000,\n", " opacity=0,\n", " stroke_color='turquoise',\n", " stroke_width=2\n", " ),\n", " legends=default_legend(title='Annual Revenue'),\n", " default_popup_hover=False,\n", " default_popup_click=False\n", " ),\n", " Layer(stores_gdf)\n", " ]),\n", " Map([\n", " Layer(\n", " iso_gdf,\n", " style=color_bins_style(\n", " 'inccymedhh',\n", " bins=7,\n", " palette='pinkyl',\n", " stroke_width=0\n", " ),\n", " legends=default_legend(title='Median Income'),\n", " default_popup_hover=False,\n", " default_popup_click=False\n", " ),\n", " Layer(stores_gdf)\n", " ]),\n", " Map([\n", " Layer(iso_gdf,\n", " style=color_bins_style(\n", " 'popcy',\n", " bins=7,\n", " palette='pinkyl',\n", " stroke_width=0\n", " ),\n", " legends=default_legend(title='Total Pop'),\n", " default_popup_hover=False,\n", " default_popup_click=False\n", " ),\n", " Layer(stores_gdf)\n", " ]),\n", " Map([\n", " Layer(\n", " iso_gdf,\n", " style=color_bins_style(\n", " 'lbfcyempl',\n", " bins=7,\n", " palette='pinkyl',\n", " stroke_width=0\n", " ),\n", " legends=default_legend(title='Employed Pop'),\n", " default_popup_hover=False,\n", " default_popup_click=False\n", " ),\n", " Layer(stores_gdf)\n", " ]),\n", "],2,2,viewport={'zoom': 10, 'lat': 40.64, 'lng': -73.92}, map_height=400, is_static=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Conclusion\n", "\n", "In this guide you were introduced to the Map and Layer classes, saw how to explore data with Widgets and Popups, and how to use visualization styles to quickly symbolize thematic attributes. You also saw some options for creating different maps of your findings.\n" ] } ], "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.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }