diff --git a/docs/examples/jupyter-notebooks-dev/livemap_tile_provider_config.ipynb b/docs/examples/jupyter-notebooks-dev/livemap_tile_provider_config.ipynb
index 9cb4d5221f6..b5e60168736 100644
--- a/docs/examples/jupyter-notebooks-dev/livemap_tile_provider_config.ipynb
+++ b/docs/examples/jupyter-notebooks-dev/livemap_tile_provider_config.ipynb
@@ -14,29 +14,9 @@
"cell_type": "code",
"execution_count": 2,
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " \n",
- " "
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
- "LetsPlot.setup_html()"
+ "LetsPlot.setup_html(isolated_frame=True, offline=False)"
]
},
{
@@ -47,10 +27,14 @@
{
"data": {
"text/html": [
- "
\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"lbq8RU\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 3,
@@ -104,10 +88,14 @@
{
"data": {
"text/html": [
- " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"T9Vk0l\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 4,
@@ -163,10 +150,14 @@
{
"data": {
"text/html": [
- " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"FXfWMC\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 5,
@@ -222,10 +212,14 @@
{
"data": {
"text/html": [
- " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"v3Xk18\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 6,
@@ -289,10 +282,14 @@
{
"data": {
"text/html": [
- " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"68kpYp\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 8,
@@ -347,10 +343,14 @@
{
"data": {
"text/html": [
- " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"qBL9lP\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 9,
@@ -406,10 +405,14 @@
{
"data": {
"text/html": [
- " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
" "
+ " var plotContainer = document.getElementById(\"YapJIa\");\n",
+ " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
+ " \n",
+ " \n",
+ ""
],
"text/plain": [
- ""
+ ""
]
},
"execution_count": 10,
@@ -453,6 +455,64 @@
"# raster tiles config directly to the livemap while vector tiles are in global settings\n",
"ggplot() + geom_livemap(tiles='https://a.tile.openstreetmap.org/{z}/{x}/{y}.png')"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ ""
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ggplot() + geom_livemap(tiles='http://tile.stamen.com/terrain/{z}/{x}/{y}.png')"
+ ]
}
],
"metadata": {
diff --git a/docs/examples/jupyter-notebooks-dev/map_US_household_income_new.ipynb b/docs/examples/jupyter-notebooks-dev/map_US_household_income_new.ipynb
index c3d2897366c..a5af8175076 100644
--- a/docs/examples/jupyter-notebooks-dev/map_US_household_income_new.ipynb
+++ b/docs/examples/jupyter-notebooks-dev/map_US_household_income_new.ipynb
@@ -1942,7 +1942,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.8"
+ "version": "3.7.6"
}
},
"nbformat": 4,
diff --git a/docs/examples/jupyter-notebooks-dev/map_US_household_income_new_ik.ipynb b/docs/examples/jupyter-notebooks-dev/map_US_household_income_new_ik.ipynb
index 9b8226b3c33..dac31ba96dd 100644
--- a/docs/examples/jupyter-notebooks-dev/map_US_household_income_new_ik.ipynb
+++ b/docs/examples/jupyter-notebooks-dev/map_US_household_income_new_ik.ipynb
@@ -2,13 +2,43 @@
"cells": [
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The geodata is provided by © OpenStreetMap contributors and is made available here under the Open Database License (ODbL).\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " \n",
+ " "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
"from lets_plot import *\n",
"from lets_plot.geo_data import *\n",
"\n",
+ "from lets_plot.settings_utils import geocoding_service\n",
+ "#LetsPlot.set(geocoding_service(url='http://3.86.228.157:3025'))\n",
+ "\n",
"import pandas as pd\n",
"\n",
"LetsPlot.setup_html()"
@@ -16,9 +46,144 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " id | \n",
+ " State_Code | \n",
+ " State_Name | \n",
+ " State_ab | \n",
+ " County | \n",
+ " City | \n",
+ " Place | \n",
+ " Type | \n",
+ " Primary | \n",
+ " Zip_Code | \n",
+ " Area_Code | \n",
+ " ALand | \n",
+ " AWater | \n",
+ " Lat | \n",
+ " Lon | \n",
+ " Mean | \n",
+ " Median | \n",
+ " Stdev | \n",
+ " sum_w | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 1011000 | \n",
+ " 1 | \n",
+ " Alabama | \n",
+ " AL | \n",
+ " Mobile County | \n",
+ " Chickasaw | \n",
+ " Chickasaw city | \n",
+ " City | \n",
+ " place | \n",
+ " 36611 | \n",
+ " 251 | \n",
+ " 10894952 | \n",
+ " 909156 | \n",
+ " 30.771450 | \n",
+ " -88.079697 | \n",
+ " 38773 | \n",
+ " 30506 | \n",
+ " 33101 | \n",
+ " 1638.260513 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 1011010 | \n",
+ " 1 | \n",
+ " Alabama | \n",
+ " AL | \n",
+ " Barbour County | \n",
+ " Louisville | \n",
+ " Clio city | \n",
+ " City | \n",
+ " place | \n",
+ " 36048 | \n",
+ " 334 | \n",
+ " 26070325 | \n",
+ " 23254 | \n",
+ " 31.708516 | \n",
+ " -85.611039 | \n",
+ " 37725 | \n",
+ " 19528 | \n",
+ " 43789 | \n",
+ " 258.017685 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 1011020 | \n",
+ " 1 | \n",
+ " Alabama | \n",
+ " AL | \n",
+ " Shelby County | \n",
+ " Columbiana | \n",
+ " Columbiana city | \n",
+ " City | \n",
+ " place | \n",
+ " 35051 | \n",
+ " 205 | \n",
+ " 44835274 | \n",
+ " 261034 | \n",
+ " 33.191452 | \n",
+ " -86.615618 | \n",
+ " 54606 | \n",
+ " 31930 | \n",
+ " 57348 | \n",
+ " 926.031000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " id State_Code State_Name State_ab County City \\\n",
+ "0 1011000 1 Alabama AL Mobile County Chickasaw \n",
+ "1 1011010 1 Alabama AL Barbour County Louisville \n",
+ "2 1011020 1 Alabama AL Shelby County Columbiana \n",
+ "\n",
+ " Place Type Primary Zip_Code Area_Code ALand AWater \\\n",
+ "0 Chickasaw city City place 36611 251 10894952 909156 \n",
+ "1 Clio city City place 36048 334 26070325 23254 \n",
+ "2 Columbiana city City place 35051 205 44835274 261034 \n",
+ "\n",
+ " Lat Lon Mean Median Stdev sum_w \n",
+ "0 30.771450 -88.079697 38773 30506 33101 1638.260513 \n",
+ "1 31.708516 -85.611039 37725 19528 43789 258.017685 \n",
+ "2 33.191452 -86.615618 54606 31930 57348 926.031000 "
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"income_all = pd.read_csv('../data/US_household_income_2017.csv', encoding='latin-1')\n",
"income_all.head(3)"
@@ -26,9 +191,66 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " State_Name | \n",
+ " Mean | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Alabama | \n",
+ " 53612.925856 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Alaska | \n",
+ " 77670.209524 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Arizona | \n",
+ " 62578.071313 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " State_Name Mean\n",
+ "0 Alabama 53612.925856\n",
+ "1 Alaska 77670.209524\n",
+ "2 Arizona 62578.071313"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"income_by_state = income_all.groupby(\"State_Name\", as_index=False)[\"Mean\"].mean()\n",
"income_by_state.head(3)"
@@ -36,170 +258,1372 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " State_Name | \n",
+ " County | \n",
+ " Mean | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Alabama | \n",
+ " Autauga County | \n",
+ " 53735.557235 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Alabama | \n",
+ " Barbour County | \n",
+ " 37725.000000 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Alabama | \n",
+ " Blount County | \n",
+ " 55127.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " State_Name County Mean\n",
+ "0 Alabama Autauga County 53735.557235\n",
+ "1 Alabama Barbour County 37725.000000\n",
+ "2 Alabama Blount County 55127.000000"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "# load coordinates of US states in low resolution\n",
- "states = regions_state('US-48').boundaries(resolution=4)\n",
- "states.head(3)"
+ "income_by_county = income_all.groupby([\"State_Name\",\"County\"], as_index=False)[\"Mean\"].mean()\n",
+ "income_by_county.head(3)"
]
},
{
- "cell_type": "markdown",
+ "cell_type": "code",
+ "execution_count": 5,
"metadata": {},
+ "outputs": [],
"source": [
- "#### Blank map"
+ "us48 = regions_state('us-48').to_data_frame()['found name'].tolist()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1629\n"
+ ]
+ }
+ ],
"source": [
- "map_theme = theme(axis_line=\"blank\", axis_text=\"blank\", axis_title=\"blank\", axis_ticks=\"blank\") + ggsize(900, 400)\n",
- "ggplot() + geom_map(map=states) + map_theme"
+ "data = income_by_county\n",
+ "data = data[data.State_Name.isin(us48)]\n",
+ "row_count, _ = data.shape\n",
+ "print(row_count)"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
- "ggplot(income_by_state) + geom_map(aes(fill=\"Mean\"), map=states, map_join=[\"State_Name\", \"request\"]) + map_theme \\\n",
- " + scale_fill_gradient(low=\"#007BCD\", high=\"#FE0968\", name=\"Mean income\")"
+ "counties = regions_builder2('county', \n",
+ " names=data[\"County\"].tolist(), \n",
+ " states=data[\"State_Name\"].tolist())\\\n",
+ " .drop_not_matched()\\\n",
+ " .build()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 8,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " id | \n",
+ " request | \n",
+ " found name | \n",
+ " state | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 3697517 | \n",
+ " Autauga County | \n",
+ " Autauga County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 3701595 | \n",
+ " Barbour County | \n",
+ " Barbour County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 3697523 | \n",
+ " Blount County | \n",
+ " Blount County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 3697525 | \n",
+ " Butler County | \n",
+ " Butler County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 3701599 | \n",
+ " Chambers County | \n",
+ " Chambers County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 1612 | \n",
+ " 578649 | \n",
+ " Platte County | \n",
+ " Platte County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1613 | \n",
+ " 577321 | \n",
+ " Sheridan County | \n",
+ " Sheridan County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1614 | \n",
+ " 2822805 | \n",
+ " Sweetwater County | \n",
+ " Sweetwater County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1615 | \n",
+ " 578695 | \n",
+ " Uinta County | \n",
+ " Uinta County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1616 | \n",
+ " 578671 | \n",
+ " Weston County | \n",
+ " Weston County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
1617 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " id request found name state\n",
+ "0 3697517 Autauga County Autauga County Alabama\n",
+ "1 3701595 Barbour County Barbour County Alabama\n",
+ "2 3697523 Blount County Blount County Alabama\n",
+ "3 3697525 Butler County Butler County Alabama\n",
+ "4 3701599 Chambers County Chambers County Alabama\n",
+ "... ... ... ... ...\n",
+ "1612 578649 Platte County Platte County Wyoming\n",
+ "1613 577321 Sheridan County Sheridan County Wyoming\n",
+ "1614 2822805 Sweetwater County Sweetwater County Wyoming\n",
+ "1615 578695 Uinta County Uinta County Wyoming\n",
+ "1616 578671 Weston County Weston County Wyoming\n",
+ "\n",
+ "[1617 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "scale_fill_gradient2?"
+ "counties.to_data_frame()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 9,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " request | \n",
+ " found name | \n",
+ " state | \n",
+ " geometry | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Autauga County | \n",
+ " Autauga County | \n",
+ " Alabama | \n",
+ " POINT (-86.65117 32.50771) | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Barbour County | \n",
+ " Barbour County | \n",
+ " Alabama | \n",
+ " POINT (-85.39351 31.88341) | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Blount County | \n",
+ " Blount County | \n",
+ " Alabama | \n",
+ " POINT (-86.53304 34.01333) | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " Butler County | \n",
+ " Butler County | \n",
+ " Alabama | \n",
+ " POINT (-86.67532 31.73537) | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " Chambers County | \n",
+ " Chambers County | \n",
+ " Alabama | \n",
+ " POINT (-85.39419 32.92209) | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 1612 | \n",
+ " Platte County | \n",
+ " Platte County | \n",
+ " Wyoming | \n",
+ " POINT (-104.96764 42.12731) | \n",
+ "
\n",
+ " \n",
+ " 1613 | \n",
+ " Sheridan County | \n",
+ " Sheridan County | \n",
+ " Wyoming | \n",
+ " POINT (-106.90375 44.77929) | \n",
+ "
\n",
+ " \n",
+ " 1614 | \n",
+ " Sweetwater County | \n",
+ " Sweetwater County | \n",
+ " Wyoming | \n",
+ " POINT (-108.98868 41.63776) | \n",
+ "
\n",
+ " \n",
+ " 1615 | \n",
+ " Uinta County | \n",
+ " Uinta County | \n",
+ " Wyoming | \n",
+ " POINT (-110.54782 41.28135) | \n",
+ "
\n",
+ " \n",
+ " 1616 | \n",
+ " Weston County | \n",
+ " Weston County | \n",
+ " Wyoming | \n",
+ " POINT (-104.56841 43.84001) | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
1617 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " request found name state \\\n",
+ "0 Autauga County Autauga County Alabama \n",
+ "1 Barbour County Barbour County Alabama \n",
+ "2 Blount County Blount County Alabama \n",
+ "3 Butler County Butler County Alabama \n",
+ "4 Chambers County Chambers County Alabama \n",
+ "... ... ... ... \n",
+ "1612 Platte County Platte County Wyoming \n",
+ "1613 Sheridan County Sheridan County Wyoming \n",
+ "1614 Sweetwater County Sweetwater County Wyoming \n",
+ "1615 Uinta County Uinta County Wyoming \n",
+ "1616 Weston County Weston County Wyoming \n",
+ "\n",
+ " geometry \n",
+ "0 POINT (-86.65117 32.50771) \n",
+ "1 POINT (-85.39351 31.88341) \n",
+ "2 POINT (-86.53304 34.01333) \n",
+ "3 POINT (-86.67532 31.73537) \n",
+ "4 POINT (-85.39419 32.92209) \n",
+ "... ... \n",
+ "1612 POINT (-104.96764 42.12731) \n",
+ "1613 POINT (-106.90375 44.77929) \n",
+ "1614 POINT (-108.98868 41.63776) \n",
+ "1615 POINT (-110.54782 41.28135) \n",
+ "1616 POINT (-104.56841 43.84001) \n",
+ "\n",
+ "[1617 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "# Issue: 'request' in the result is empty.\n",
- "counties = regions_county(within=\"US-48\").boundaries(resolution=4)\n",
- "counties.head(3)"
+ "centroids=counties.centroids()\n",
+ "centroids"
]
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {
- "scrolled": false
- },
- "outputs": [],
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " request | \n",
+ " found name | \n",
+ " state | \n",
+ " geometry | \n",
+ " State_Name | \n",
+ " County | \n",
+ " Mean | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Autauga County | \n",
+ " Autauga County | \n",
+ " Alabama | \n",
+ " POINT (-86.65117 32.50771) | \n",
+ " Alabama | \n",
+ " Autauga County | \n",
+ " 53735.557235 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Barbour County | \n",
+ " Barbour County | \n",
+ " Alabama | \n",
+ " POINT (-85.39351 31.88341) | \n",
+ " Alabama | \n",
+ " Barbour County | \n",
+ " 37725.000000 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Blount County | \n",
+ " Blount County | \n",
+ " Alabama | \n",
+ " POINT (-86.53304 34.01333) | \n",
+ " Alabama | \n",
+ " Blount County | \n",
+ " 55127.000000 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " Butler County | \n",
+ " Butler County | \n",
+ " Alabama | \n",
+ " POINT (-86.67532 31.73537) | \n",
+ " Alabama | \n",
+ " Butler County | \n",
+ " 27993.000000 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " Chambers County | \n",
+ " Chambers County | \n",
+ " Alabama | \n",
+ " POINT (-85.39419 32.92209) | \n",
+ " Alabama | \n",
+ " Chambers County | \n",
+ " 45107.000000 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 1612 | \n",
+ " Platte County | \n",
+ " Platte County | \n",
+ " Wyoming | \n",
+ " POINT (-104.96764 42.12731) | \n",
+ " Wyoming | \n",
+ " Platte County | \n",
+ " 127999.000000 | \n",
+ "
\n",
+ " \n",
+ " 1613 | \n",
+ " Sheridan County | \n",
+ " Sheridan County | \n",
+ " Wyoming | \n",
+ " POINT (-106.90375 44.77929) | \n",
+ " Wyoming | \n",
+ " Sheridan County | \n",
+ " 68733.000000 | \n",
+ "
\n",
+ " \n",
+ " 1614 | \n",
+ " Sweetwater County | \n",
+ " Sweetwater County | \n",
+ " Wyoming | \n",
+ " POINT (-108.98868 41.63776) | \n",
+ " Wyoming | \n",
+ " Sweetwater County | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " 1615 | \n",
+ " Uinta County | \n",
+ " Uinta County | \n",
+ " Wyoming | \n",
+ " POINT (-110.54782 41.28135) | \n",
+ " Wyoming | \n",
+ " Uinta County | \n",
+ " 89130.000000 | \n",
+ "
\n",
+ " \n",
+ " 1616 | \n",
+ " Weston County | \n",
+ " Weston County | \n",
+ " Wyoming | \n",
+ " POINT (-104.56841 43.84001) | \n",
+ " Wyoming | \n",
+ " Weston County | \n",
+ " 69215.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
1617 rows × 7 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " request found name state \\\n",
+ "0 Autauga County Autauga County Alabama \n",
+ "1 Barbour County Barbour County Alabama \n",
+ "2 Blount County Blount County Alabama \n",
+ "3 Butler County Butler County Alabama \n",
+ "4 Chambers County Chambers County Alabama \n",
+ "... ... ... ... \n",
+ "1612 Platte County Platte County Wyoming \n",
+ "1613 Sheridan County Sheridan County Wyoming \n",
+ "1614 Sweetwater County Sweetwater County Wyoming \n",
+ "1615 Uinta County Uinta County Wyoming \n",
+ "1616 Weston County Weston County Wyoming \n",
+ "\n",
+ " geometry State_Name County Mean \n",
+ "0 POINT (-86.65117 32.50771) Alabama Autauga County 53735.557235 \n",
+ "1 POINT (-85.39351 31.88341) Alabama Barbour County 37725.000000 \n",
+ "2 POINT (-86.53304 34.01333) Alabama Blount County 55127.000000 \n",
+ "3 POINT (-86.67532 31.73537) Alabama Butler County 27993.000000 \n",
+ "4 POINT (-85.39419 32.92209) Alabama Chambers County 45107.000000 \n",
+ "... ... ... ... ... \n",
+ "1612 POINT (-104.96764 42.12731) Wyoming Platte County 127999.000000 \n",
+ "1613 POINT (-106.90375 44.77929) Wyoming Sheridan County 68733.000000 \n",
+ "1614 POINT (-108.98868 41.63776) Wyoming Sweetwater County 0.000000 \n",
+ "1615 POINT (-110.54782 41.28135) Wyoming Uinta County 89130.000000 \n",
+ "1616 POINT (-104.56841 43.84001) Wyoming Weston County 69215.000000 \n",
+ "\n",
+ "[1617 rows x 7 columns]"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "ggplot() + geom_map(map=counties) + map_theme"
+ "# map_join is lacking multi-key support, so we use pandas.merge\n",
+ "data_with_geometry = centroids.merge(data, left_on=['request', 'state'], right_on=['County', 'State_Name'])\n",
+ "data_with_geometry"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 11,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "income_by_county = income_all.groupby([\"State_Name\",\"County\"], as_index=False)[\"Mean\"].mean()\n",
- "income_by_county.head(3)"
+ "ggplot() + geom_point(aes(color='Mean'), data_with_geometry)"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 12,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " request | \n",
+ " found name | \n",
+ " state | \n",
+ " geometry | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Autauga County | \n",
+ " Autauga County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-86.83594 32.39852, -86.83594 ... | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Barbour County | \n",
+ " Barbour County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-85.78125 31.65338, -85.60547 ... | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Blount County | \n",
+ " Blount County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-86.48438 34.16182, -86.30859 ... | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " Butler County | \n",
+ " Butler County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-86.83594 31.95216, -86.83594 ... | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " Chambers County | \n",
+ " Chambers County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-85.07812 32.84267, -85.07812 ... | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 1612 | \n",
+ " Platte County | \n",
+ " Platte County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-105.29297 42.55308, -105.2929... | \n",
+ "
\n",
+ " \n",
+ " 1613 | \n",
+ " Sheridan County | \n",
+ " Sheridan County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-107.92969 44.96480, -107.9296... | \n",
+ "
\n",
+ " \n",
+ " 1614 | \n",
+ " Sweetwater County | \n",
+ " Sweetwater County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-110.03906 42.03297, -110.0390... | \n",
+ "
\n",
+ " \n",
+ " 1615 | \n",
+ " Uinta County | \n",
+ " Uinta County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-111.09375 41.24477, -111.0937... | \n",
+ "
\n",
+ " \n",
+ " 1616 | \n",
+ " Weston County | \n",
+ " Weston County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-105.11719 43.58039, -105.1171... | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
1617 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " request found name state \\\n",
+ "0 Autauga County Autauga County Alabama \n",
+ "1 Barbour County Barbour County Alabama \n",
+ "2 Blount County Blount County Alabama \n",
+ "3 Butler County Butler County Alabama \n",
+ "4 Chambers County Chambers County Alabama \n",
+ "... ... ... ... \n",
+ "1612 Platte County Platte County Wyoming \n",
+ "1613 Sheridan County Sheridan County Wyoming \n",
+ "1614 Sweetwater County Sweetwater County Wyoming \n",
+ "1615 Uinta County Uinta County Wyoming \n",
+ "1616 Weston County Weston County Wyoming \n",
+ "\n",
+ " geometry \n",
+ "0 MULTIPOLYGON (((-86.83594 32.39852, -86.83594 ... \n",
+ "1 MULTIPOLYGON (((-85.78125 31.65338, -85.60547 ... \n",
+ "2 MULTIPOLYGON (((-86.48438 34.16182, -86.30859 ... \n",
+ "3 MULTIPOLYGON (((-86.83594 31.95216, -86.83594 ... \n",
+ "4 MULTIPOLYGON (((-85.07812 32.84267, -85.07812 ... \n",
+ "... ... \n",
+ "1612 MULTIPOLYGON (((-105.29297 42.55308, -105.2929... \n",
+ "1613 MULTIPOLYGON (((-107.92969 44.96480, -107.9296... \n",
+ "1614 MULTIPOLYGON (((-110.03906 42.03297, -110.0390... \n",
+ "1615 MULTIPOLYGON (((-111.09375 41.24477, -111.0937... \n",
+ "1616 MULTIPOLYGON (((-105.11719 43.58039, -105.1171... \n",
+ "\n",
+ "[1617 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "# Issue: 'Internal error', message uninformative\n",
- "ggplot(income_by_county) + geom_map(aes(fill=\"Mean\"), map=counties, map_join=[\"County\", \"request\"]) + map_theme \\\n",
- " + scale_fill_gradient(low=\"#007BCD\", high=\"#FE0968\", name=\"Mean income\", na_value=\"white\")"
+ "boundaries=counties.boundaries()\n",
+ "boundaries"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 13,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " request | \n",
+ " found name | \n",
+ " state | \n",
+ " geometry | \n",
+ " State_Name | \n",
+ " County | \n",
+ " Mean | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Autauga County | \n",
+ " Autauga County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-86.83594 32.39852, -86.83594 ... | \n",
+ " Alabama | \n",
+ " Autauga County | \n",
+ " 53735.557235 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Barbour County | \n",
+ " Barbour County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-85.78125 31.65338, -85.60547 ... | \n",
+ " Alabama | \n",
+ " Barbour County | \n",
+ " 37725.000000 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Blount County | \n",
+ " Blount County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-86.48438 34.16182, -86.30859 ... | \n",
+ " Alabama | \n",
+ " Blount County | \n",
+ " 55127.000000 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " Butler County | \n",
+ " Butler County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-86.83594 31.95216, -86.83594 ... | \n",
+ " Alabama | \n",
+ " Butler County | \n",
+ " 27993.000000 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " Chambers County | \n",
+ " Chambers County | \n",
+ " Alabama | \n",
+ " MULTIPOLYGON (((-85.07812 32.84267, -85.07812 ... | \n",
+ " Alabama | \n",
+ " Chambers County | \n",
+ " 45107.000000 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 1612 | \n",
+ " Platte County | \n",
+ " Platte County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-105.29297 42.55308, -105.2929... | \n",
+ " Wyoming | \n",
+ " Platte County | \n",
+ " 127999.000000 | \n",
+ "
\n",
+ " \n",
+ " 1613 | \n",
+ " Sheridan County | \n",
+ " Sheridan County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-107.92969 44.96480, -107.9296... | \n",
+ " Wyoming | \n",
+ " Sheridan County | \n",
+ " 68733.000000 | \n",
+ "
\n",
+ " \n",
+ " 1614 | \n",
+ " Sweetwater County | \n",
+ " Sweetwater County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-110.03906 42.03297, -110.0390... | \n",
+ " Wyoming | \n",
+ " Sweetwater County | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " 1615 | \n",
+ " Uinta County | \n",
+ " Uinta County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-111.09375 41.24477, -111.0937... | \n",
+ " Wyoming | \n",
+ " Uinta County | \n",
+ " 89130.000000 | \n",
+ "
\n",
+ " \n",
+ " 1616 | \n",
+ " Weston County | \n",
+ " Weston County | \n",
+ " Wyoming | \n",
+ " MULTIPOLYGON (((-105.11719 43.58039, -105.1171... | \n",
+ " Wyoming | \n",
+ " Weston County | \n",
+ " 69215.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
1617 rows × 7 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " request found name state \\\n",
+ "0 Autauga County Autauga County Alabama \n",
+ "1 Barbour County Barbour County Alabama \n",
+ "2 Blount County Blount County Alabama \n",
+ "3 Butler County Butler County Alabama \n",
+ "4 Chambers County Chambers County Alabama \n",
+ "... ... ... ... \n",
+ "1612 Platte County Platte County Wyoming \n",
+ "1613 Sheridan County Sheridan County Wyoming \n",
+ "1614 Sweetwater County Sweetwater County Wyoming \n",
+ "1615 Uinta County Uinta County Wyoming \n",
+ "1616 Weston County Weston County Wyoming \n",
+ "\n",
+ " geometry State_Name \\\n",
+ "0 MULTIPOLYGON (((-86.83594 32.39852, -86.83594 ... Alabama \n",
+ "1 MULTIPOLYGON (((-85.78125 31.65338, -85.60547 ... Alabama \n",
+ "2 MULTIPOLYGON (((-86.48438 34.16182, -86.30859 ... Alabama \n",
+ "3 MULTIPOLYGON (((-86.83594 31.95216, -86.83594 ... Alabama \n",
+ "4 MULTIPOLYGON (((-85.07812 32.84267, -85.07812 ... Alabama \n",
+ "... ... ... \n",
+ "1612 MULTIPOLYGON (((-105.29297 42.55308, -105.2929... Wyoming \n",
+ "1613 MULTIPOLYGON (((-107.92969 44.96480, -107.9296... Wyoming \n",
+ "1614 MULTIPOLYGON (((-110.03906 42.03297, -110.0390... Wyoming \n",
+ "1615 MULTIPOLYGON (((-111.09375 41.24477, -111.0937... Wyoming \n",
+ "1616 MULTIPOLYGON (((-105.11719 43.58039, -105.1171... Wyoming \n",
+ "\n",
+ " County Mean \n",
+ "0 Autauga County 53735.557235 \n",
+ "1 Barbour County 37725.000000 \n",
+ "2 Blount County 55127.000000 \n",
+ "3 Butler County 27993.000000 \n",
+ "4 Chambers County 45107.000000 \n",
+ "... ... ... \n",
+ "1612 Platte County 127999.000000 \n",
+ "1613 Sheridan County 68733.000000 \n",
+ "1614 Sweetwater County 0.000000 \n",
+ "1615 Uinta County 89130.000000 \n",
+ "1616 Weston County 69215.000000 \n",
+ "\n",
+ "[1617 rows x 7 columns]"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "# Issue: 'map_join' can't join tables just by county name, without state name. \n",
- "ggplot(income_by_county) + geom_map(aes(fill=\"Mean\"), map=counties, map_join=[\"County\", \"found name\"]) + map_theme \\\n",
- " + scale_fill_gradient(low=\"#007BCD\", high=\"#FE0968\", name=\"Mean income\", na_value=\"white\")"
+ "# map_join is lacking multi-key support, so we use pandas.merge\n",
+ "data_with_boundaries = boundaries.merge(data, left_on=['request', 'state'], right_on=['County', 'State_Name'])\n",
+ "data_with_boundaries\n"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "map_theme = theme(axis_line=\"blank\", axis_text=\"blank\", axis_title=\"blank\", axis_ticks=\"blank\") + ggsize(900, 400)\n",
+ "ggplot() + geom_map(aes(fill='Mean'), data_with_boundaries) + scale_fill_gradient(low=\"#007BCD\", high=\"#FE0968\", name=\"Mean income\") + map_theme"
+ ]
+ },
+ {
+ "cell_type": "markdown",
"metadata": {},
- "outputs": [],
"source": [
- "# Issue: batch query takes a lot of time and results with an error. The message is misleading:\n",
- "# ValueError: Error: Service is down for maintenance\n",
- "#regions_county(income_by_county[\"County\"].tolist(), within=income_by_county[\"State_Name\"].tolist())"
+ "Issues"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 15,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ " id request found name state country\n",
+ "0 3676279 Wayne County Wayne County New York usa\n",
+ "1 5057345 Anson County Anson County North Carolina usa"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "# Geocode USA only once\n",
- "usa = regions_country('usa')"
+ "# drop_not_found breaks parents - these columns are missing\n",
+ "regions_builder2('county', \n",
+ " names=['Wayne County', 'Not existing County', 'Anson County'],\n",
+ " states=['New York', 'New York', 'North Carolina'],\n",
+ " countries=['usa', 'usa', 'usa'])\\\n",
+ " .drop_not_found()\\\n",
+ " .build()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 16,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ " id request found name state country\n",
+ "0 3676279 Wayne County Wayne County New York usa\n",
+ "1 5068353 Essex County Essex County Virginia usa"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "def display_progress(i, n):\n",
- " def display(s):\n",
- " from IPython.display import display, clear_output, HTML\n",
- " if s:\n",
- " clear_output(wait=True)\n",
- " display(HTML(\"{}\".format(s)))\n",
- " else:\n",
- " clear_output()\n",
- " \n",
- " if i != n:\n",
- " display('Geocoding progress: {}%'.format(round(i / n * 100, 1)))\n",
- " if i == n:\n",
- " display(None)"
+ "# issue with parents geocoding - unexpected ranking behaviour results in broken responses.\n",
+ "# When mulitply object found by one request ambiguous response is generated without use of ranking by weight. \n",
+ "# Ambiguous response is also borken - it returns success response with first namesake object ¯\\_(ツ)_/¯\n",
+ "regions_builder2('county', \n",
+ " names=['Wayne County', 'Essex County'],\n",
+ " states=['New York', 'Virginia'],\n",
+ " countries=['usa', 'usa'])\\\n",
+ " .build()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 17,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "ename": "ValueError",
+ "evalue": "Countries count(1) != names count(2)",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mnames\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Wayne County'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Essex County'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'New York'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Virginia'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m countries=['usa'])\\\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mbuild\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m~/miniconda3/lib/python3.7/site-packages/lets_plot/geo_data/new_api.py\u001b[0m in \u001b[0;36mregions_builder2\u001b[0;34m(level, names, scope, countries, states, counties, highlights)\u001b[0m\n\u001b[1;32m 88\u001b[0m \u001b[0mcounties\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcounties\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 89\u001b[0m \u001b[0mnew_api\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 90\u001b[0;31m new_scope=new_scope)\n\u001b[0m",
+ "\u001b[0;32m~/miniconda3/lib/python3.7/site-packages/lets_plot/geo_data/regions_builder.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, level, request, scope, highlights, allow_ambiguous, countries, states, counties, new_api, new_scope)\u001b[0m\n\u001b[1;32m 178\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnew_api\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 179\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_scope\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mMapRegion\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew_scope\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 180\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_queries\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mRegionQuery\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_create_new_queries\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_default_ambiguity_resolver\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcountries\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcounties\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 181\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 182\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_scope\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mMapRegion\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m~/miniconda3/lib/python3.7/site-packages/lets_plot/geo_data/regions_builder.py\u001b[0m in \u001b[0;36m_create_new_queries\u001b[0;34m(request, ambiguity_resovler, countries, states, counties)\u001b[0m\n\u001b[1;32m 77\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 78\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcountries\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcountries\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequests\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 79\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Countries count({}) != names count({})'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcountries\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequests\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 80\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 81\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mstates\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstates\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequests\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Countries count(1) != names count(2)"
+ ]
+ }
+ ],
"source": [
- "# Search states once for faster counties geocoding. \n",
- "# States are duplicated but geocoding at level 'state' is pretty fast - dedup gives only 2x speed-up.\n",
- "states = regions_builder('state', income_by_county[\"State_Name\"].tolist(), within=usa)\\\n",
- " .chunk_request(display_progress) \\\n",
+ "# not informative error message\n",
+ "regions_builder2('county', \n",
+ " names=['Wayne County', 'Essex County'],\n",
+ " states=['New York', 'Virginia'],\n",
+ " countries=['usa'])\\\n",
" .build()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 19,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " id | \n",
+ " request | \n",
+ " found name | \n",
+ " state | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 3697517 | \n",
+ " Autauga County | \n",
+ " Autauga County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 3701595 | \n",
+ " Barbour County | \n",
+ " Barbour County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 3697523 | \n",
+ " Blount County | \n",
+ " Blount County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 3697525 | \n",
+ " Butler County | \n",
+ " Butler County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 3701599 | \n",
+ " Chambers County | \n",
+ " Chambers County | \n",
+ " Alabama | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 1612 | \n",
+ " 578649 | \n",
+ " Platte County | \n",
+ " Platte County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1613 | \n",
+ " 577321 | \n",
+ " Sheridan County | \n",
+ " Sheridan County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1614 | \n",
+ " 2822805 | \n",
+ " Sweetwater County | \n",
+ " Sweetwater County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1615 | \n",
+ " 578695 | \n",
+ " Uinta County | \n",
+ " Uinta County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ " 1616 | \n",
+ " 578671 | \n",
+ " Weston County | \n",
+ " Weston County | \n",
+ " Wyoming | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
1617 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " id request found name state\n",
+ "0 3697517 Autauga County Autauga County Alabama\n",
+ "1 3701595 Barbour County Barbour County Alabama\n",
+ "2 3697523 Blount County Blount County Alabama\n",
+ "3 3697525 Butler County Butler County Alabama\n",
+ "4 3701599 Chambers County Chambers County Alabama\n",
+ "... ... ... ... ...\n",
+ "1612 578649 Platte County Platte County Wyoming\n",
+ "1613 577321 Sheridan County Sheridan County Wyoming\n",
+ "1614 2822805 Sweetwater County Sweetwater County Wyoming\n",
+ "1615 578695 Uinta County Uinta County Wyoming\n",
+ "1616 578671 Weston County Weston County Wyoming\n",
+ "\n",
+ "[1617 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "# Geocode counties with already geocoded states for better performance.\n",
- "counties = regions_builder('county', income_by_county[\"County\"].tolist(), within=states)\\\n",
- " .chunk_request(display_progress) \\\n",
- " .build()"
+ "# regions in parent is not yet supported\n",
+ "state_regions = regions_builder2('state', names=data[\"State_Name\"].tolist(), countries=['uSa'] * row_count).build()\n",
+ "counties_via_regions = regions_builder2('county', \n",
+ " names=data[\"County\"].tolist(), \n",
+ " states=state_regions)\\\n",
+ " .drop_not_matched()\\\n",
+ " .build()\n",
+ "counties_via_regions.to_data_frame()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ " id request found name\n",
+ "0 3270329 florida Florida"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "regions_builder2('state', names=['florida'], scope='Uruguay').build()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ " id request found name country\n",
+ "0 324101 florida Florida usa\n",
+ "1 3270329 florida Florida Uruguay"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "regions_builder2('state', names=['florida', 'florida'], countries=['usa', 'Uruguay']).build()"
]
}
],
diff --git a/docs/geocoding.md b/docs/geocoding.md
index 77764dce46d..629fe28345b 100644
--- a/docs/geocoding.md
+++ b/docs/geocoding.md
@@ -11,60 +11,69 @@ Geocoding is the process of converting names of places into geographic coordinat
*Lets-Plot* geocoding API allows a user to execute a single and batch geocoding queries, and handle possible
names ambiguity.
-Relatively simple geocoding queries are executed using the `regions_xxx()` functions family. For example:
+The core class is `Geocoder`. There is a function's family for constsructing the `Geocoder` object - `geocode_cities()`, `geocode_counties()`, `geocode_states()`, `geocode_countries()` and `geocode()`. For example:
```python
from lets_plot.geo_data import *
-regions_country(['usa', 'canada'])
+countries = geocode_countries(['usa', 'canada'])
```
-returns the `Regions` object containing internal IDs for Canada and the US:
+Notice that actual geocoding process is not happening here, it starts when any `get_xxx()` function get called. For this document I will use function `get_geocodes()` that returns `DataFrame` with metadata. It is usefull for testing.
+
+Lets geocode countries:
+```python
+countries.get_geocodes()
+```
+returns the `DataFrame` object containing internal IDs for Canada and the US:
```
- request id found name
-0 usa 297677 United States of America
-1 canada 2856251 Canada
+ |id |request |found name
+----------------------------------
+0 |297677 |usa |United States
+1 |2856251 |canada |Canada
```
-More complex geocoding queries can be created with the help of the `regions_builder()` function that
-returns the `RegionsBuilder` object and allows chaining its various methods in order to specify
+More complex geocoding queries can be created with the help of the `Geocoder` object by chaining its various methods in order to specify
how to handle geocoding ambiguities.
For example:
```python
-regions_builder(request='warwick', level='city') \
+geocode_cities('warwick') \
.allow_ambiguous() \
- .build()
+ .get_geocodes()
```
-This sample returns the `Regions` object containing IDs of all cities matching "warwick":
-```
- request id found name
-0 warwick 785807 Warwick
-1 warwick 363189 Warwick
-2 warwick 352173 Warwick
-3 warwick 15994531 Warwick
-4 warwick 368499 Warwick
-5 warwick 239553 Warwick
-6 warwick 352897 Warwick
-7 warwick 3679247 Warwick
-8 warwick 8144841 Warwick
-9 warwick 382429 West Warwick
-10 warwick 7042961 Warwick Township
-11 warwick 6098747 Warwick Township
-12 warwick 15994533 Sainte-Élizabeth-de-Warwick
+This sample returns the `DataFrame` object containing IDs of all cities matching "warwick":
+```
+
+ |id |request |found name
+----------------------------------------------------
+0 |239553 |warwick |Warwick
+1 |352173 |warwick |Warwick
+2 |352897 |warwick |Warwick
+3 |363189 |warwick |Warwick
+4 |368499 |warwick |Warwick
+5 |785807 |warwick |Warwick
+6 |3679247 |warwick |Warwick
+7 |8144841 |warwick |Warwick
+8 |15994531 |warwick |Warwick
+9 |382429 |warwick |West Warwick
+10 |6098747 |warwick |Warwick Township
+11 |7042961 |warwick |Warwick Township
+12 |18489127 |warwick |Warwick Mountain
+13 |15994533 |warwick |Sainte-Élizabeth-de-Warwick
```
```python
-boston_us = regions(request='boston', within='us')
-regions_builder(request='warwick', level='city') \
- .where('warwick', near=boston_us) \
- .build()
+boston_us = geocode_cities('boston').scope('us')
+geocode_cities('warwick') \
+ .where('warwick', closest_to=boston_us) \
+ .get_geocodes()
```
-This example returns the `Regions` object containing the ID of one particular "warwick" near Boston (US):
+This example returns the `DataFrame` object containing the ID of one particular "warwick" closest to Boston (US):
```
- request id found name
-0 warwick 785807 Warwick
+ |id |request |found name
+------------------------------
+0 |785807 |warwick |Warwick
```
-Once the `Regions` object is available, it can be passed to any *Lets-Plot* geom
+Once the `Geocoder` object is available, it can be passed to any *Lets-Plot* geom
supporting the `map` parameter.
-If necessary, the `Regions` object can be transformed into a regular pandas `DataFrame` using `to_data_frame()` method
-or to a geopandas `GeoDataFrame` using one of `centroids()`, `boundaries()`, or `limits()` methods.
+If necessary, the `Geocoder` object can be transformed to a geopandas `GeoDataFrame` using one of `get_centroids()`, `get_boundaries()`, or `get_limits()` methods.
All coordinates are in the EPSG:4326 coordinate reference system (CRS).
@@ -96,4 +105,288 @@ Examples:
-
\ No newline at end of file
+
+
+## Reference
+
+#### Levels
+Geocoding supports 4 administrative levels:
+- city
+- county
+- state
+- country
+
+
+Function `geocode()` with `level=None` can try to detect level automatically - it enumerates all levels from country to city and selects best matching level (result without ambiguity and unknown names). For example:
+```python
+geocode(names=['florida', 'tx']).get_geocodes()
+```
+
+```
+ |id |request |found name
+------------------------------
+0 |324101 |florida |Florida
+1 |229381 |tx |Texas
+```
+While it is usefull it works slower and is not recomended to use on large data sets.
+
+
+Functions `geocode_cities()`, `geocode_counties()`, `geocode_states()`, `geocode_countries()` or `geocode(level=xxx)` search names only at a given level or return an error.
+```python
+geocode_states(['florida', 'tx']).get_geocodes()
+```
+
+
+
+#### Parents
+`Geocoder` class provides functions for defining parents with giving administrative level - `counties()`, `states()`, `countries()`. Functions can handle single or miltiply values of types string or `Geocoder`. Number of values must match number of names in `Geocoder` so they form a table, i.e. every name associated by an index with coresponding parent. Parents will be present in result `DataFrame` to make it possible to join data and geometry via `map_join`.
+
+```python
+geocode_cities(['warwick', 'worcester'])\
+ .counties(['Worth County', 'worcester county'])\
+ .states(['georgia', 'massachusetts'])\
+ .get_geocodes()
+```
+```
+ |id | request |found name |county |state
+--------------------------------------------------------------
+0 |239553 | warwick |Warwick |Worth County |georgia
+1 |3688419 | worcester |Worcester |worcester county |massachusetts
+```
+
+Parents can contain `None` values, e.g., countries having different administrative division:
+```python
+geocode_cities(['warwick', 'worcester'])\
+ .states(['Georgia', None])\
+ .countries(['USA', 'United Kingdom'])\
+ .get_geocodes()
+```
+```
+
+ |id |request |found name |state |country
+--------------------------------------------------------------
+0 |239553 |warwick |Warwick |Georgia |USA
+1 |3750683 |worcester |Worcester |None |United Kingdom
+```
+
+Parent can be `Geocoder` object. This allows resolving parent's ambiguity:
+```python
+
+s = geocode_states(['vermont', 'georgia']).scope('usa')
+geocode_cities(['worcester', 'warwick']).states(s).get_geocodes()
+```
+```
+ |id |request |found name |state
+-------------------------------------------
+0 |17796275 |worcester |Worcester |vermont
+1 |239553 |warwick |Warwick |georgia
+```
+
+##### Scope
+`scope()` is a special kind of parent. `scope()` can handle a `string` or a single entry `Geocoder` object. `scope()` is not associated with any administrative level, it acts as parent for any other parents (or names if no other parents set). `scope()` can't be used with `countries()` - countries don't have parents. Typical use-case is when all names belong to the same parent - you don't need to generate list with required length to pass it as a parent, just use the `scope()` with single value.
+
+```python
+geocode_counties(['Dakota County', 'Nevada County']).states(['NE', 'AR']).scope('USA').get_geocodes()
+```
+```
+ |id |request |found name |state
+------------------------------------------------
+0 |2850895 |Dakota County |Dakota County |NE
+1 |3653651 |Nevada County |Nevada County |AR
+```
+
+Parents can be modified between searches:
+
+```python
+florida = geocode_states('florida')
+
+display(florida.countries('usa').get_geocodes())
+display(florida.countries('uruguay').get_geocodes())
+display(florida.countries(None).get_geocodes())
+```
+
+```
+id |request |found name |country
+------------------------------------
+324101 |florida |Florida |usa
+
+id |request |found name |country
+------------------------------------
+3270329|florida |Florida |uruguay
+
+id |request |found name
+---------------------------
+324101 |florida |Florida
+```
+##### Fetch all
+
+It is possible to fetch all objects within parent - just don't set the `names` parameter.
+
+```python
+geocode_counties().states('massachusetts').get_geocodes()
+```
+
+```
+ |id |request |found name |state
+-------------------------------------------------------------
+0 |2363239 |Hampden County |Hampden County |massachusetts
+1 |122643 |Berkshire County |Berkshire County |massachusetts
+2 |180869 |Essex County |Essex County |massachusetts
+3 |3677609 |Hampshire County |Hampshire County |massachusetts
+4 |3677611 |Worcester County |Worcester County |massachusetts
+...
+```
+
+##### US-48 (CONUS)
+Geocoding supports a special name - `us-48` also known as CONUS. This name can be used as name or parent.
+```python
+geocode_states('us-48').get_geocodes()
+```
+```
+ |id |request |found name
+---------------------------------------
+0 |121519 |Vermont |Vermont
+1 |122631 |Massachusetts |Massachusetts
+2 |122641 |New York |New York
+3 |127025 |Maine |Maine
+4 |134427 |New Hampshire |New Hampshire
+...
+```
+
+#### Ambiguity
+Often geocoding can find multiply objects for a name or don't find anything. in this case error will be generated:
+ ```python
+geocode_cities(['warwick', 'worcester']).get_geocodes()
+```
+```
+Multiple objects (14) were found for warwick:
+
+- Warwick (United States, Georgia, Worth County)
+- Warwick (United States, New York, Orange County)
+- Warwick (United Kingdom, England, West Midlands, Warwickshire)
+- Warwick (United States, North Dakota, Benson County)
+- Warwick (United States, Oklahoma, Lincoln County)
+- Warwick (United States, Rhode Island, Kent County)
+- Warwick (United States, Massachusetts, Franklin County)
+- Warwick (Canada, Ontario, Southwestern Ontario, Lambton County)
+- Warwick (Canada, Québec, Centre-du-Québec, Arthabaska)
+- West Warwick (United States, Rhode Island, Kent County) Multiple objects (4) were found for worcester:
+- Worcester (United States, Massachusetts, Worcester County)
+- Worcester (United Kingdom, England, West Midlands, Worcestershire)
+- Worcester (United States, Vermont, Washington County)
+- Worcester Township (United States, Pennsylvania, Montgomery County)
+```
+
+The ambiguity can be resolved in different ways.
+
+##### `allow_ambiguous()`
+
+The best way is to find an object that we search and use its parents. Function `allow_ambiguous()` converts error result into success result that can be rendered on a map or verified manually in other way.
+
+```python
+geocode_cities(['warwick', 'worcester']).allow_ambiguous().get_geocodes()
+```
+```
+ |id |request |found name
+------------------------------
+0 |239553 |warwick |Warwick
+1 |352173 |warwick |Warwick
+2 |352897 |warwick |Warwick
+3 |363189 |warwick |Warwick
+4 |368499 |warwick |Warwick
+```
+
+##### `sksip_missing()`
+The function `drop_not_found()` removes unknown names from result.
+```python
+geocode_cities(['paris', 'foo']).drop_not_found().get_geocodes()
+```
+
+```
+ |id |request |found name
+-----------------------------
+0 |14889 |paris |Paris
+```
+
+##### `drop_not_matched()`
+If request contains both unknown and ambiguous names then `drop_not_matched()` function can be used to remove them all from result.
+```python
+geocode_cities(['paris', 'worcester', 'foo']).drop_not_matched().get_geocodes()
+```
+```
+ |id |request |found name
+-----------------------------
+0 |14889 |paris |Paris
+```
+
+##### `where()`
+For resolving an ambiguity geocoding provides a function that can configure names individually.
+To configure a name the function `where(...)` should be called with the place name and all given parent names. Parents can't be changed via `where()` function call. If name and parents don't match with ones from the `where()` function an error will be generated. This is importnant for cases like this:
+```python
+geocode_counties(['Washington', 'Washington']).states(['oregon', 'utah']).get_geocodes()
+```
+```
+ |id |request |found name |state
+-------------------------------------------------
+0 |3674267 |Washington |Washington County |oregon
+1 |3488745 |Washington |Washington County |utah
+```
+
+With parameter `closest_to` geocoding will take the only object that is closest to it. Parameter can be a single value `Geocoder`.
+```python
+boston = geocode_cities('boston')
+geocode_cities('worcester').where('worcester', closest_to=boston).get_geocodes()
+```
+
+```
+ |id |request |found name
+---------------------------------
+0 |3688419 |worcester |Worcester
+```
+Or parameter can be a `shapely.geometry.Point`.
+```python
+geocode_cities('worcester').where('worcester', closest_to=shapely.geometry.Point(-71.088, 42.311)).get_geocodes()
+```
+```
+ |id |request |found name
+---------------------------------
+0 |3688419 |worcester |Worcester
+```
+
+With parameter `scope` a `shapely.geometry.Polygon` can be used for limiting an area of the search (coordinates should be in WGS84 cordinate system). Notice that bbox of the polygon will be used:
+```python
+geocode_cities('worcester')\
+ .where('worcester', scope=shapely.geometry.box(-71.00, 42.00, -72.00, 43.00))\
+ .get_geocodes()
+```
+```
+ |id |request |found name
+---------------------------------
+0 |3688419 |worcester |Worcester
+```
+
+Also, `scope` can be a single value `Geocoder` object or a `string`:
+```python
+massachusetts = geocode_states('massachusetts')
+geocode_cities('worcester').where('worcester', scope=massachusetts).get_geocodes()
+```
+
+`scope` doesn't change parents in a result `DataFrame`:
+```python
+worcester_county=geocode_counties('Worcester County').states('massachusetts').countries('usa')
+
+geocode_cities(['worcester', 'worcester'])\
+ .countries(['USA', 'United Kingdom'])\
+ .where('worcester', country='USA', scope=worcester_county)\
+ .get_geocodes()
+```
+
+```
+ |id |request |found name |country
+-------------------------------------------------
+0 |3688419 |worcester |Worcester |USA
+1 |3750683 |worcester |Worcester |United Kingdom
+```
+
+## `map_join`
+WIP
\ No newline at end of file
diff --git a/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt b/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt
index 4b0a693a216..48246b0fb0e 100644
--- a/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt
+++ b/livemap-demo/src/commonMain/kotlin/jetbrains/livemap/plotDemo/LiveMap.kt
@@ -12,8 +12,11 @@ import kotlin.random.Random
class LiveMap : PlotConfigDemoBase() {
fun plotSpecList(): List