Repository: CartoDB/cartoframes
Pull request #1537 (2020-02-12 16:18:15)

Add option to sort legends in descending order [ch58612]
This PR adds a parameter to the legends to be able to sort values in descending order. To be merged along with:

- Airship: https://github.com/CartoDB/airship/pull/677
- CARTO VL: https://github.com/CartoDB/carto-vl/pull/1429

To Do:
- [x] Add tests
- [x] Add to reference
- [x] Add example


Patch:
diff --git a/cartoframes/assets/src/bundle.js b/cartoframes/assets/src/bundle.js
index c48b673a..c4636d3b 100644
--- a/cartoframes/assets/src/bundle.js
+++ b/cartoframes/assets/src/bundle.js
@@ -407,8 +407,9 @@ var init = (function () {
       const othersLabel = 'Others';   // TODO: i18n
       const prop = legend.prop;
       const dynamic = legend.dynamic;
+      const order = legend.ascending ? 'ASC' : 'DESC';
       const variable = legend.variable;
-      const config = { othersLabel, variable };
+      const config = { othersLabel, variable, order };
       const options = { format, config, dynamic };
 
       if (legend.type.startsWith('size-continuous')) {
diff --git a/cartoframes/assets/src/legends.js b/cartoframes/assets/src/legends.js
index d8fc805f..2b131c7b 100644
--- a/cartoframes/assets/src/legends.js
+++ b/cartoframes/assets/src/legends.js
@@ -15,8 +15,9 @@ function _createLegend(layer, legend, layerIndex, legendIndex, mapIndex=0) {
     const othersLabel = 'Others';   // TODO: i18n
     const prop = legend.prop;
     const dynamic = legend.dynamic;
+    const order = legend.ascending ? 'ASC' : 'DESC';
     const variable = legend.variable;
-    const config = { othersLabel, variable };
+    const config = { othersLabel, variable, order };
     const options = { format, config, dynamic };
 
     if (legend.type.startsWith('size-continuous')) {
diff --git a/cartoframes/viz/constants.py b/cartoframes/viz/constants.py
index 921cca77..17f1ad4d 100644
--- a/cartoframes/viz/constants.py
+++ b/cartoframes/viz/constants.py
@@ -2,7 +2,7 @@ CARTO_VL_VERSION = 'v1.4'
 CARTO_VL_DEV = '/dist/carto-vl.js'
 CARTO_VL_URL = 'https://libs.cartocdn.com/carto-vl/{}/carto-vl.min.js'.format(CARTO_VL_VERSION)
 
-AIRSHIP_VERSION = 'v2.2'
+AIRSHIP_VERSION = 'v2.3'
 AIRSHIP_COMPONENTS_DEV = '/packages/components/dist/airship.js'
 AIRSHIP_BRIDGE_DEV = '/packages/bridge/dist/asbridge.js'
 AIRSHIP_MODULE_DEV = '/packages/components/dist/airship/airship.esm.js'
diff --git a/cartoframes/viz/legend.py b/cartoframes/viz/legend.py
index fab86b38..a341cc7f 100644
--- a/cartoframes/viz/legend.py
+++ b/cartoframes/viz/legend.py
@@ -15,7 +15,7 @@ class Legend:
 
     """
     def __init__(self, legend_type=None, title=None, description=None,
-                 footer=None, prop=None, variable='', dynamic=True):
+                 footer=None, prop=None, variable='', dynamic=True, ascending=False):
         self._check_type(legend_type)
         self._check_prop(prop)
         self._type = legend_type
@@ -25,6 +25,7 @@ class Legend:
         self._prop = prop
         self._variable = variable
         self._dynamic = dynamic
+        self._ascending = ascending
 
     def add_defaults(self, title=None):
         self._title = self._title or title
@@ -42,6 +43,7 @@ class Legend:
                 'prop': _prop,
                 'variable': self._variable,
                 'dynamic': self._dynamic,
+                'ascending': self._ascending,
                 'title': self._title or '',
                 'description': self._description or '',
                 'footer': self._footer or ''
diff --git a/cartoframes/viz/legends/color_bins_legend.py b/cartoframes/viz/legends/color_bins_legend.py
index 0c8253d4..f7693266 100644
--- a/cartoframes/viz/legends/color_bins_legend.py
+++ b/cartoframes/viz/legends/color_bins_legend.py
@@ -2,7 +2,7 @@ from ..legend import Legend
 
 
 def color_bins_legend(title=None, description=None, footer=None, prop='color',
-                      variable=None, dynamic=True):
+                      variable=None, dynamic=True, ascending=False):
     """Helper function for quickly creating a color bins legend.
 
     Args:
@@ -33,4 +33,4 @@ def color_bins_legend(title=None, description=None, footer=None, prop='color',
         ...     dynamic=False)
 
     """
-    return Legend('color-bins', title, description, footer, prop, variable, dynamic)
+    return Legend('color-bins', title, description, footer, prop, variable, dynamic, ascending)
diff --git a/cartoframes/viz/legends/color_category_legend.py b/cartoframes/viz/legends/color_category_legend.py
index b0bdf55c..4b408db4 100644
--- a/cartoframes/viz/legends/color_category_legend.py
+++ b/cartoframes/viz/legends/color_category_legend.py
@@ -2,7 +2,7 @@ from ..legend import Legend
 
 
 def color_category_legend(title=None, description=None, footer=None, prop='color',
-                          variable=None, dynamic=True):
+                          variable=None, dynamic=True, ascending=False):
     """Helper function for quickly creating a color category legend.
 
     Args:
@@ -33,4 +33,4 @@ def color_category_legend(title=None, description=None, footer=None, prop='color
         ...     dynamic=False)
 
     """
-    return Legend('color-category', title, description, footer, prop, variable, dynamic)
+    return Legend('color-category', title, description, footer, prop, variable, dynamic, ascending)
diff --git a/cartoframes/viz/legends/color_continuous_legend.py b/cartoframes/viz/legends/color_continuous_legend.py
index 3727cee2..97b596d2 100644
--- a/cartoframes/viz/legends/color_continuous_legend.py
+++ b/cartoframes/viz/legends/color_continuous_legend.py
@@ -2,7 +2,7 @@ from ..legend import Legend
 
 
 def color_continuous_legend(title=None, description=None, footer=None, prop='color',
-                            variable=None, dynamic=True):
+                            variable=None, dynamic=True, ascending=False):
     """Helper function for quickly creating a color continuous legend.
 
     Args:
@@ -33,4 +33,4 @@ def color_continuous_legend(title=None, description=None, footer=None, prop='col
         ...     dynamic=False)
 
     """
-    return Legend('color-continuous', title, description, footer, prop, variable, dynamic)
+    return Legend('color-continuous', title, description, footer, prop, variable, dynamic, ascending)
diff --git a/cartoframes/viz/legends/size_bins_legend.py b/cartoframes/viz/legends/size_bins_legend.py
index f293df21..b2f18e7e 100644
--- a/cartoframes/viz/legends/size_bins_legend.py
+++ b/cartoframes/viz/legends/size_bins_legend.py
@@ -2,7 +2,7 @@ from ..legend import Legend
 
 
 def size_bins_legend(title=None, description=None, footer=None, prop='size',
-                     variable=None, dynamic=True):
+                     variable=None, dynamic=True, ascending=False):
     """Helper function for quickly creating a size bins legend.
 
     Args:
@@ -33,4 +33,4 @@ def size_bins_legend(title=None, description=None, footer=None, prop='size',
         ...     dynamic=False)
 
     """
-    return Legend('size-bins', title, description, footer, prop, variable, dynamic)
+    return Legend('size-bins', title, description, footer, prop, variable, dynamic, ascending)
diff --git a/cartoframes/viz/legends/size_category_legend.py b/cartoframes/viz/legends/size_category_legend.py
index 9d437536..3f9b30d0 100644
--- a/cartoframes/viz/legends/size_category_legend.py
+++ b/cartoframes/viz/legends/size_category_legend.py
@@ -2,7 +2,7 @@ from ..legend import Legend
 
 
 def size_category_legend(title=None, description=None, footer=None, prop='size',
-                         variable=None, dynamic=True):
+                         variable=None, dynamic=True, ascending=False):
     """Helper function for quickly creating a size category legend.
 
     Args:
@@ -34,4 +34,4 @@ def size_category_legend(title=None, description=None, footer=None, prop='size',
         ...     dynamic=False)
 
     """
-    return Legend('size-category', title, description, footer, prop, variable, dynamic)
+    return Legend('size-category', title, description, footer, prop, variable, dynamic, ascending)
diff --git a/cartoframes/viz/legends/size_continuous_legend.py b/cartoframes/viz/legends/size_continuous_legend.py
index 35086d63..e54516c0 100644
--- a/cartoframes/viz/legends/size_continuous_legend.py
+++ b/cartoframes/viz/legends/size_continuous_legend.py
@@ -2,7 +2,7 @@ from ..legend import Legend
 
 
 def size_continuous_legend(title=None, description=None, footer=None, prop='size',
-                           variable='size_value', dynamic=True):
+                           variable='size_value', dynamic=True, ascending=False):
     """Helper function for quickly creating a size continuous legend.
 
     Args:
@@ -32,4 +32,4 @@ def size_continuous_legend(title=None, description=None, footer=None, prop='size
         ...     dynamic=False)
 
     """
-    return Legend('size-continuous', title, description, footer, prop, variable, dynamic)
+    return Legend('size-continuous', title, description, footer, prop, variable, dynamic, ascending)
diff --git a/examples/data_services/isodistances.ipynb b/examples/data_services/isodistances.ipynb
index 60cb8299..33b836f9 100644
--- a/examples/data_services/isodistances.ipynb
+++ b/examples/data_services/isodistances.ipynb
@@ -2012,10 +2012,10 @@
     }
    ],
    "source": [
-    "from cartoframes.viz import Map, Layer, basic_style\n",
+    "from cartoframes.viz import Map, Layer\n",
     "\n",
     "Map([\n",
-    "    Layer(isodistances_gdf, basic_style(color='green', opacity='0.3')),\n",
+    "    Layer(isodistances_gdf, 'color: opacity(green, 0.3)'),\n",
     "    Layer(gdf, 'width: 3')\n",
     "])"
    ]
@@ -2037,7 +2037,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.4"
+   "version": "3.6.7"
   }
  },
  "nbformat": 4,
diff --git a/examples/legends/default_legend.ipynb b/examples/legends/default_legend.ipynb
index 85e7e3ed..a4e310b9 100644
--- a/examples/legends/default_legend.ipynb
+++ b/examples/legends/default_legend.ipynb
@@ -9,7 +9,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -49,11 +49,11 @@
        "  <link href=&quot;https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css&quot; rel=&quot;stylesheet&quot; />\n",
        "\n",
        "  <!-- Include Airship -->\n",
-       "  <script nomodule=&quot;&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.2.0-rc.2.2/airship.js&quot;></script>\n",
-       "  <script type=&quot;module&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.2.0-rc.2.2/airship/airship.esm.js&quot;></script>\n",
-       "  <script src=&quot;https://libs.cartocdn.com/airship-bridge/v2.2.0-rc.2.2/asbridge.min.js&quot;></script>\n",
-       "  <link href=&quot;https://libs.cartocdn.com/airship-style/v2.2.0-rc.2.2/airship.min.css&quot; rel=&quot;stylesheet&quot;>\n",
-       "  <link href=&quot;https://libs.cartocdn.com/airship-icons/v2.2.0-rc.2.2/icons.css&quot; rel=&quot;stylesheet&quot;>\n",
+       "  <script nomodule=&quot;&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.3/airship.js&quot;></script>\n",
+       "  <script type=&quot;module&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.3/airship/airship.esm.js&quot;></script>\n",
+       "  <script src=&quot;https://libs.cartocdn.com/airship-bridge/v2.3/asbridge.min.js&quot;></script>\n",
+       "  <link href=&quot;https://libs.cartocdn.com/airship-style/v2.3/airship.min.css&quot; rel=&quot;stylesheet&quot;>\n",
+       "  <link href=&quot;https://libs.cartocdn.com/airship-icons/v2.3/icons.css&quot; rel=&quot;stylesheet&quot;>\n",
        "\n",
        "  <link href=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;>\n",
        "\n",
@@ -674,8 +674,9 @@
        "      const othersLabel = 'Others';   // TODO: i18n\n",
        "      const prop = legend.prop;\n",
        "      const dynamic = legend.dynamic;\n",
+       "      const order = legend.ascending ? 'ASC' : 'DESC';\n",
        "      const variable = legend.variable;\n",
-       "      const config = { othersLabel, variable };\n",
+       "      const config = { othersLabel, variable, order };\n",
        "      const options = { format, config, dynamic };\n",
        "\n",
        "      if (legend.type.startsWith('size-continuous')) {\n",
@@ -920,7 +921,7 @@
        "    const camera = null;\n",
        "    const has_legends = 'true' === 'true';\n",
        "    const is_static = 'None' === 'true';\n",
-       "    const layers = [{&quot;credentials&quot;: {&quot;api_key&quot;: &quot;default_public&quot;, &quot;base_url&quot;: &quot;https://cartoframes.carto.com&quot;, &quot;username&quot;: &quot;cartoframes&quot;}, &quot;data&quot;: &quot;SELECT * FROM \\&quot;cartoframes\\&quot;.\\&quot;demographics_sf\\&quot;&quot;, &quot;has_legend_list&quot;: true, &quot;interactivity&quot;: [{&quot;attrs&quot;: {&quot;name&quot;: &quot;vb4e077&quot;, &quot;title&quot;: &quot;masters_percent&quot;}, &quot;event&quot;: &quot;hover&quot;}], &quot;legends&quot;: [{&quot;description&quot;: &quot;&quot;, &quot;dynamic&quot;: true, &quot;footer&quot;: &quot;&quot;, &quot;prop&quot;: &quot;color&quot;, &quot;title&quot;: &quot;Percent Master\\u0027s Degree&quot;, &quot;type&quot;: &quot;color-bins&quot;, &quot;variable&quot;: &quot;&quot;}], &quot;options&quot;: {}, &quot;type&quot;: &quot;Query&quot;, &quot;viz&quot;: &quot;@vb4e077: $masters_percent\\ncolor: opacity(ramp(globalQuantiles($masters_percent, 5), purpor), 0.9)\\nstrokeWidth: ramp(linear(zoom(),2,18),[0.5,1])\\nstrokeColor: opacity(#2c2c2c,ramp(linear(zoom(),2,18),[0.2,0.6]))\\nfilter: 1\\n&quot;, &quot;widgets&quot;: []}];\n",
+       "    const layers = [{&quot;credentials&quot;: {&quot;api_key&quot;: &quot;default_public&quot;, &quot;base_url&quot;: &quot;https://cartoframes.carto.com&quot;, &quot;username&quot;: &quot;cartoframes&quot;}, &quot;data&quot;: &quot;SELECT * FROM \\&quot;cartoframes\\&quot;.\\&quot;demographics_sf\\&quot;&quot;, &quot;has_legend_list&quot;: true, &quot;interactivity&quot;: [{&quot;attrs&quot;: {&quot;name&quot;: &quot;vb4e077&quot;, &quot;title&quot;: &quot;masters_percent&quot;}, &quot;event&quot;: &quot;hover&quot;}], &quot;legends&quot;: [{&quot;ascending&quot;: false, &quot;description&quot;: &quot;&quot;, &quot;dynamic&quot;: true, &quot;footer&quot;: &quot;&quot;, &quot;prop&quot;: &quot;color&quot;, &quot;title&quot;: &quot;Percent Master\\u0027s Degree&quot;, &quot;type&quot;: &quot;color-bins&quot;, &quot;variable&quot;: &quot;&quot;}], &quot;options&quot;: {}, &quot;type&quot;: &quot;Query&quot;, &quot;viz&quot;: &quot;@vb4e077: $masters_percent\\ncolor: opacity(ramp(globalQuantiles($masters_percent, 5), purpor), 0.9)\\nstrokeWidth: ramp(linear(zoom(),2,18),[0.5,1])\\nstrokeColor: opacity(#2c2c2c,ramp(linear(zoom(),2,18),[0.2,0.6]))\\nfilter: 1\\n&quot;, &quot;widgets&quot;: []}];\n",
        "    const mapboxtoken = '';\n",
        "    const show_info = 'None' === 'true';\n",
        "\n",
@@ -943,7 +944,7 @@
        "</iframe>"
       ],
       "text/plain": [
-       "<cartoframes.viz.map.Map at 0x10fc3b2d0>"
+       "<cartoframes.viz.map.Map at 0x10f9be2d0>"
       ]
      },
      "execution_count": 7,
@@ -965,7 +966,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 8,
    "metadata": {},
    "outputs": [
     {
@@ -994,11 +995,11 @@
        "  <link href=&quot;https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css&quot; rel=&quot;stylesheet&quot; />\n",
        "\n",
        "  <!-- Include Airship -->\n",
-       "  <script nomodule=&quot;&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.2.0-rc.2.2/airship.js&quot;></script>\n",
-       "  <script type=&quot;module&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.2.0-rc.2.2/airship/airship.esm.js&quot;></script>\n",
-       "  <script src=&quot;https://libs.cartocdn.com/airship-bridge/v2.2.0-rc.2.2/asbridge.min.js&quot;></script>\n",
-       "  <link href=&quot;https://libs.cartocdn.com/airship-style/v2.2.0-rc.2.2/airship.min.css&quot; rel=&quot;stylesheet&quot;>\n",
-       "  <link href=&quot;https://libs.cartocdn.com/airship-icons/v2.2.0-rc.2.2/icons.css&quot; rel=&quot;stylesheet&quot;>\n",
+       "  <script nomodule=&quot;&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.3/airship.js&quot;></script>\n",
+       "  <script type=&quot;module&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.3/airship/airship.esm.js&quot;></script>\n",
+       "  <script src=&quot;https://libs.cartocdn.com/airship-bridge/v2.3/asbridge.min.js&quot;></script>\n",
+       "  <link href=&quot;https://libs.cartocdn.com/airship-style/v2.3/airship.min.css&quot; rel=&quot;stylesheet&quot;>\n",
+       "  <link href=&quot;https://libs.cartocdn.com/airship-icons/v2.3/icons.css&quot; rel=&quot;stylesheet&quot;>\n",
        "\n",
        "  <link href=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;>\n",
        "\n",
@@ -1619,8 +1620,9 @@
        "      const othersLabel = 'Others';   // TODO: i18n\n",
        "      const prop = legend.prop;\n",
        "      const dynamic = legend.dynamic;\n",
+       "      const order = legend.ascending ? 'ASC' : 'DESC';\n",
        "      const variable = legend.variable;\n",
-       "      const config = { othersLabel, variable };\n",
+       "      const config = { othersLabel, variable, order };\n",
        "      const options = { format, config, dynamic };\n",
        "\n",
        "      if (legend.type.startsWith('size-continuous')) {\n",
@@ -1865,7 +1867,7 @@
        "    const camera = null;\n",
        "    const has_legends = 'true' === 'true';\n",
        "    const is_static = 'None' === 'true';\n",
-       "    const layers = [{&quot;credentials&quot;: {&quot;api_key&quot;: &quot;default_public&quot;, &quot;base_url&quot;: &quot;https://cartoframes.carto.com&quot;, &quot;username&quot;: &quot;cartoframes&quot;}, &quot;data&quot;: &quot;SELECT * FROM \\&quot;cartoframes\\&quot;.\\&quot;demographics_sf\\&quot;&quot;, &quot;has_legend_list&quot;: true, &quot;interactivity&quot;: [{&quot;attrs&quot;: {&quot;name&quot;: &quot;vb4e077&quot;, &quot;title&quot;: &quot;masters_percent&quot;}, &quot;event&quot;: &quot;hover&quot;}], &quot;legends&quot;: [{&quot;description&quot;: &quot;&quot;, &quot;dynamic&quot;: true, &quot;footer&quot;: &quot;&quot;, &quot;prop&quot;: &quot;color&quot;, &quot;title&quot;: &quot;masters_percent&quot;, &quot;type&quot;: &quot;color-bins&quot;, &quot;variable&quot;: null}], &quot;options&quot;: {}, &quot;type&quot;: &quot;Query&quot;, &quot;viz&quot;: &quot;@vb4e077: $masters_percent\\ncolor: opacity(ramp(globalQuantiles($masters_percent, 5), purpor), 0.9)\\nstrokeWidth: ramp(linear(zoom(),2,18),[0.5,1])\\nstrokeColor: opacity(#2c2c2c,ramp(linear(zoom(),2,18),[0.2,0.6]))\\nfilter: 1\\n&quot;, &quot;widgets&quot;: []}];\n",
+       "    const layers = [{&quot;credentials&quot;: {&quot;api_key&quot;: &quot;default_public&quot;, &quot;base_url&quot;: &quot;https://cartoframes.carto.com&quot;, &quot;username&quot;: &quot;cartoframes&quot;}, &quot;data&quot;: &quot;SELECT * FROM \\&quot;cartoframes\\&quot;.\\&quot;demographics_sf\\&quot;&quot;, &quot;has_legend_list&quot;: true, &quot;interactivity&quot;: [{&quot;attrs&quot;: {&quot;name&quot;: &quot;vb4e077&quot;, &quot;title&quot;: &quot;masters_percent&quot;}, &quot;event&quot;: &quot;hover&quot;}], &quot;legends&quot;: [{&quot;ascending&quot;: false, &quot;description&quot;: &quot;&quot;, &quot;dynamic&quot;: true, &quot;footer&quot;: &quot;&quot;, &quot;prop&quot;: &quot;color&quot;, &quot;title&quot;: &quot;masters_percent&quot;, &quot;type&quot;: &quot;color-bins&quot;, &quot;variable&quot;: null}], &quot;options&quot;: {}, &quot;type&quot;: &quot;Query&quot;, &quot;viz&quot;: &quot;@vb4e077: $masters_percent\\ncolor: opacity(ramp(globalQuantiles($masters_percent, 5), purpor), 0.9)\\nstrokeWidth: ramp(linear(zoom(),2,18),[0.5,1])\\nstrokeColor: opacity(#2c2c2c,ramp(linear(zoom(),2,18),[0.2,0.6]))\\nfilter: 1\\n&quot;, &quot;widgets&quot;: []}];\n",
        "    const mapboxtoken = '';\n",
        "    const show_info = 'None' === 'true';\n",
        "\n",
@@ -1888,10 +1890,10 @@
        "</iframe>"
       ],
       "text/plain": [
-       "<cartoframes.viz.map.Map at 0x10fc3b590>"
+       "<cartoframes.viz.map.Map at 0x10f9be390>"
       ]
      },
-     "execution_count": 6,
+     "execution_count": 8,
      "metadata": {},
      "output_type": "execute_result"
     }
diff --git a/examples/legends/multiple_layer_legends.ipynb b/examples/legends/multiple_layer_legends.ipynb
new file mode 100644
index 00000000..4b6d2eb8
--- /dev/null
+++ b/examples/legends/multiple_layer_legends.ipynb
@@ -0,0 +1,32 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.7.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/examples/legends/size_continuous_legend.ipynb b/examples/legends/size_continuous_legend.ipynb
index 05bfd318..cfc43cc7 100644
--- a/examples/legends/size_continuous_legend.ipynb
+++ b/examples/legends/size_continuous_legend.ipynb
@@ -56,11 +56,11 @@
        "  <link href=&quot;https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css&quot; rel=&quot;stylesheet&quot; />\n",
        "\n",
        "  <!-- Include Airship -->\n",
-       "  <script nomodule=&quot;&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.2.0-rc.2.2/airship.js&quot;></script>\n",
-       "  <script type=&quot;module&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.2.0-rc.2.2/airship/airship.esm.js&quot;></script>\n",
-       "  <script src=&quot;https://libs.cartocdn.com/airship-bridge/v2.2.0-rc.2.2/asbridge.min.js&quot;></script>\n",
-       "  <link href=&quot;https://libs.cartocdn.com/airship-style/v2.2.0-rc.2.2/airship.min.css&quot; rel=&quot;stylesheet&quot;>\n",
-       "  <link href=&quot;https://libs.cartocdn.com/airship-icons/v2.2.0-rc.2.2/icons.css&quot; rel=&quot;stylesheet&quot;>\n",
+       "  <script nomodule=&quot;&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.3/airship.js&quot;></script>\n",
+       "  <script type=&quot;module&quot; src=&quot;https://libs.cartocdn.com/airship-components/v2.3/airship/airship.esm.js&quot;></script>\n",
+       "  <script src=&quot;https://libs.cartocdn.com/airship-bridge/v2.3/asbridge.min.js&quot;></script>\n",
+       "  <link href=&quot;https://libs.cartocdn.com/airship-style/v2.3/airship.min.css&quot; rel=&quot;stylesheet&quot;>\n",
+       "  <link href=&quot;https://libs.cartocdn.com/airship-icons/v2.3/icons.css&quot; rel=&quot;stylesheet&quot;>\n",
        "\n",
        "  <link href=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;>\n",
        "\n",
@@ -224,27 +224,32 @@
        "        \n",
        "        \n",
        "          <div class=&quot;as-map-panels&quot; data-name=&quot;Legends&quot;>\n",
-       "            <div class=&quot;as-panel as-panel--left as-panel--top&quot;>\n",
+       "            <div class=&quot;as-panel as-panel--vertical as-panel--left as-panel--top&quot;>\n",
        "              \n",
        "\n",
        "<div class=&quot;as-panel__element&quot; id=&quot;legends&quot;>\n",
-       "  \n",
-       "    \n",
+       "  <as-layer-selector id=&quot;layer-selector&quot;>\n",
        "    \n",
        "      \n",
        "        \n",
-       "          <as-legend\n",
-       "            heading=&quot;Crime Counts&quot;\n",
-       "            description=&quot;by neighborhood&quot;>\n",
-       "            <as-legend-size-continuous id=&quot;layer0_map0_legend0&quot; slot=&quot;legends&quot;></as-legend-size-continuous>\n",
+       "        \n",
+       "        <div slot=&quot;as-checkbox-layer-0-slot&quot;>\n",
+       "          \n",
        "            \n",
-       "              <span slot=&quot;footer&quot;>Source: City of SF</span>\n",
+       "              <as-legend\n",
+       "                heading=&quot;Crime Counts&quot;\n",
+       "                description=&quot;by neighborhood&quot;>\n",
+       "                <as-legend-size-continuous id=&quot;layer0_map0_legend0&quot; slot=&quot;legends&quot;></as-legend-size-continuous>\n",
+       "                \n",
+       "                  <span slot=&quot;footer&quot;>Source: City of SF</span>\n",
+       "                \n",
+       "              </as-legend>\n",
        "            \n",
-       "          </as-legend>\n",
-       "        \n",
+       "          \n",
+       "        </div>\n",
        "      \n",
        "    \n",
-       "  \n",
+       "  </as-layer-selector>\n",
        "</div>\n",
        "            </div> <!-- as-panel -->\n",
        "          </div> <!-- as-map-panels -->\n",
@@ -256,8 +261,6 @@
        "  \n",
        "\n",
        "  <div id=&quot;error-container&quot; class=&quot;error&quot;>\n",
-       "  <p>There is a <span class=&quot;errors&quot; id=&quot;error-highlight&quot;></span>\n",
-       "  from the <a href=&quot;https://carto.com/developers/carto-vl/&quot; target=&quot;_blank&quot;>CARTO VL</a> library:</p>\n",
        "  <section class=&quot;error-section&quot;>\n",
        "    <span class=&quot;errors&quot; id=&quot;error-name&quot;></span>:\n",
        "    <section id=&quot;error-content&quot;>\n",
@@ -395,9 +398,8 @@
        "    const stacktrace$ = document.getElementById('error-stacktrace');\n",
        "\n",
        "    errors$[0].innerHTML = e.name;\n",
-       "    errors$[1].innerHTML = e.name;\n",
-       "    errors$[2].innerHTML = e.type;\n",
-       "    errors$[3].innerHTML = e.message.replace(e.type, '');\n",
+       "    errors$[1].innerHTML = e.type;\n",
+       "    errors$[2].innerHTML = e.message.replace(e.type, '');\n",
        "\n",
        "    error$.style.visibility = 'visible';\n",
        "\n",
@@ -705,7 +707,7 @@
        "\n",
        "  function GeoJSON(layer) {\n",
        "    const options = JSON.parse(JSON.stringify(layer.options));\n",
-       "    const data = _decodeJSONData(layer.data);\n",
+       "    const data = _decodeJSONData(layer.data, layer.encode_data);\n",
        "\n",
        "    return new carto.source.GeoJSON(data, options);\n",
        "  }\n",
@@ -727,8 +729,20 @@
        "    return new carto.source.MVT(layer.data.file, JSON.parse(layer.data.metadata));\n",
        "  }\n",
        "\n",
-       "  function _decodeJSONData(b64Data) {\n",
-       "    return JSON.parse(pako.inflate(atob(b64Data), { to: 'string' }));\n",
+       "  function _decodeJSONData(data, encodeData) {\n",
+       "    try {\n",
+       "      if (encodeData) {\n",
+       "        const decodedJSON = pako.inflate(atob(data), { to: 'string' });\n",
+       "        return JSON.parse(decodedJSON);\n",
+       "      } else {\n",
+       "        return JSON.parse(data);\n",
+       "      }\n",
+       "    } catch(error) {\n",
+       "      throw new Error(`\n",
+       "      Error: &quot;${error}&quot;. CARTOframes is not able to parse your local data because it is too large.\n",
+       "      Please, disable the data compresion with encode_data=False in your Layer class.\n",
+       "    `);\n",
+       "    }\n",
        "  }\n",
        "\n",
        "  const factory = new SourceFactory();\n",
@@ -853,6 +867,10 @@
        "      mapIndex\n",
        "    );\n",
        "\n",
+       "    if (settings.layer_selector) {\n",
+       "      addLayersSelector(layers.reverse(), mapLayers.reverse());\n",
+       "    }\n",
+       "\n",
        "    setInteractiveLayers(map, layers, mapLayers);\n",
        "\n",
        "    return waitForMapLayersLoad(isStatic, mapIndex, mapLayers);\n",
@@ -888,6 +906,21 @@
        "    }\n",
        "  }\n",
        "\n",
+       "  function addLayersSelector(layers, mapLayers) {\n",
+       "    const layerSelector$ = document.querySelector(`#layer-selector`);\n",
+       "      const layersInfo = mapLayers.map((layer, index) => {\n",
+       "        return {\n",
+       "          title: layers[index].title || `Layer ${index}`,\n",
+       "          id: layer.id,\n",
+       "          checked: true\n",
+       "        };\n",
+       "      });\n",
+       "    \n",
+       "    const layerSelector = new AsBridge.VL.Layers(layerSelector$, carto, layersInfo, mapLayers);\n",
+       "    \n",
+       "    layerSelector.build();\n",
+       "  }\n",
+       "\n",
        "  function createMap(container, basemapStyle, bounds, accessToken) {\n",
        "    const map = createMapboxGLMap(container, basemapStyle, accessToken);\n",
        "\n",
@@ -929,7 +962,8 @@
        "    const camera = null;\n",
        "    const has_legends = 'true' === 'true';\n",
        "    const is_static = 'None' === 'true';\n",
-       "    const layers = [{&quot;credentials&quot;: {&quot;api_key&quot;: &quot;default_public&quot;, &quot;base_url&quot;: &quot;https://cartoframes.carto.com&quot;, &quot;username&quot;: &quot;cartoframes&quot;}, &quot;data&quot;: &quot;SELECT * FROM \\&quot;cartoframes\\&quot;.\\&quot;sf_nbhd_crime\\&quot;&quot;, &quot;has_legend_list&quot;: true, &quot;interactivity&quot;: [{&quot;attrs&quot;: {&quot;name&quot;: &quot;v101966&quot;, &quot;title&quot;: &quot;value&quot;}, &quot;event&quot;: &quot;hover&quot;}], &quot;legends&quot;: [{&quot;description&quot;: &quot;by neighborhood&quot;, &quot;dynamic&quot;: true, &quot;footer&quot;: &quot;Source: City of SF&quot;, &quot;prop&quot;: &quot;width&quot;, &quot;title&quot;: &quot;Crime Counts&quot;, &quot;type&quot;: &quot;size-continuous&quot;, &quot;variable&quot;: &quot;size_value&quot;}], &quot;options&quot;: {}, &quot;type&quot;: &quot;Query&quot;, &quot;viz&quot;: &quot;@v101966: $value\\ncolor: opacity(#FFB927, 0.8)\\nwidth: ramp(linear(sqrt($value), sqrt(globalMIN($value)), sqrt(globalMAX($value))), [8, 40])\\nstrokeWidth: ramp(linear(zoom(),0,18),[0,1])\\nstrokeColor: opacity(#222,ramp(linear(zoom(),0,18),[0,0.6]))\\n@size_value: ramp(linear($value, globalMIN($value), globalMAX($value)), [8, 40])\\nfilter: 1\\n&quot;, &quot;widgets&quot;: []}];\n",
+       "    const layer_selector = 'False' === 'true'; // TODO it will be a helper\n",
+       "    const layers = [{&quot;credentials&quot;: {&quot;api_key&quot;: &quot;default_public&quot;, &quot;base_url&quot;: &quot;https://cartoframes.carto.com&quot;, &quot;username&quot;: &quot;cartoframes&quot;}, &quot;data&quot;: &quot;SELECT * FROM \\&quot;cartoframes\\&quot;.\\&quot;sf_nbhd_crime\\&quot;&quot;, &quot;encode_data&quot;: true, &quot;has_legend_list&quot;: true, &quot;interactivity&quot;: [{&quot;attrs&quot;: {&quot;name&quot;: &quot;v101966&quot;, &quot;title&quot;: &quot;value&quot;}, &quot;event&quot;: &quot;hover&quot;}], &quot;legends&quot;: [{&quot;description&quot;: &quot;by neighborhood&quot;, &quot;dynamic&quot;: true, &quot;footer&quot;: &quot;Source: City of SF&quot;, &quot;prop&quot;: &quot;width&quot;, &quot;title&quot;: &quot;Crime Counts&quot;, &quot;type&quot;: &quot;size-continuous&quot;, &quot;variable&quot;: &quot;size_value&quot;}], &quot;options&quot;: {}, &quot;title&quot;: null, &quot;type&quot;: &quot;Query&quot;, &quot;viz&quot;: &quot;@v101966: $value\\ncolor: opacity(#FFB927, 0.8)\\nwidth: ramp(linear(sqrt($value), sqrt(globalMIN($value)), sqrt(globalMAX($value))), [8, 40])\\nstrokeWidth: ramp(linear(zoom(),0,18),[0,1])\\nstrokeColor: opacity(#222,ramp(linear(zoom(),0,18),[0,0.6]))\\n@size_value: ramp(linear($value, globalMIN($value), globalMAX($value)), [8, 40])\\nfilter: 1\\n&quot;, &quot;widgets&quot;: []}];\n",
        "    const mapboxtoken = '';\n",
        "    const show_info = 'None' === 'true';\n",
        "\n",
@@ -940,6 +974,7 @@
        "      camera,\n",
        "      has_legends,\n",
        "      is_static,\n",
+       "      layer_selector,\n",
        "      layers,\n",
        "      mapboxtoken,\n",
        "      show_info\n",
@@ -952,7 +987,7 @@
        "</iframe>"
       ],
       "text/plain": [
-       "<cartoframes.viz.layer.Layer at 0x1161d5ad0>"
+       "<cartoframes.viz.layer.Layer at 0x11408b990>"
       ]
      },
      "execution_count": 2,


Test patch:
diff --git a/tests/unit/viz/test_legend.py b/tests/unit/viz/test_legend.py
index 29f15814..f7185afa 100644
--- a/tests/unit/viz/test_legend.py
+++ b/tests/unit/viz/test_legend.py
@@ -32,6 +32,7 @@ class TestLegend(object):
                         footer='[footer]')
 
         assert legend.get_info() == {
+            'ascending': False,
             'type': 'color-category',
             'prop': 'color',
             'title': '[title]',