9. Interactive Data Visualization#

9.1. Introduction#

9.2. Learning Objectives#

9.3. Sample Datasets#

9.4. Installation and Setup#

# %pip install -U leafmap
import duckdb
import leafmap.maplibregl as leafmap

9.5. Downloading Sample Data#

url = "https://data.gishub.org/duckdb/nyc_data.db.zip"
leafmap.download_file(url, unzip=True)

9.6. Connecting to DuckDB and Loading Extensions#

con = duckdb.connect("nyc_data.db")

9.6.1. Installing and Loading the Spatial Extension#

con.install_extension("spatial")
con.load_extension("spatial")

9.6.2. Exploring the Database Contents#

con.sql("SHOW TABLES;")

9.7. Visualizing Point Data#

9.7.1. Querying and Converting Point Data#

subway_stations_df = con.sql(
    "SELECT * EXCLUDE geom, ST_AsText(geom) as geometry FROM nyc_subway_stations"
).df()
subway_stations_df.head()

9.7.2. Transforming to GeoDataFrame with CRS Conversion#

subway_stations_gdf = leafmap.df_to_gdf(
    subway_stations_df, src_crs="EPSG:26918", dst_crs="EPSG:4326"
)
subway_stations_gdf.head()

9.7.3. Creating a Basic Point Map#

m = leafmap.Map(style="liberty")
m.add_vector(subway_stations_gdf, name="Subway Stations")
m

9.7.4. Customizing Point Symbology#

m = leafmap.Map(style="liberty")
paint = {
    "circle-radius": 5,
    "circle-color": "#ff0000",
    "circle-opacity": 0.5,
    "circle-stroke-color": "#ffffff",
    "circle-stroke-width": 1,
}
m.add_vector(
    subway_stations_gdf, layer_type="circle", paint=paint, name="Subway Stations"
)
m

9.8. Visualizing Line Data#

9.8.1. Querying and Converting Line Data#

streets_df = con.sql(
    "SELECT * EXCLUDE geom, ST_AsText(geom) as geometry FROM nyc_streets"
).df()
streets_df.head()

9.8.2. Transforming Streets to GeoDataFrame#

streets_gdf = leafmap.df_to_gdf(streets_df, src_crs="EPSG:26918", dst_crs="EPSG:4326")
streets_gdf.head()

9.8.3. Creating a Basic Line Map#

m = leafmap.Map(style="liberty")
m.add_vector(streets_gdf, name="Streets")
m

9.8.4. Customizing Line Symbology#

m = leafmap.Map(style="liberty")
paint = {"line-color": "#ff0000", "line-width": 2, "line-opacity": 0.5}
m.add_vector(streets_gdf, layer_type="line", paint=paint, name="Streets")
m

9.9. Visualizing Polygon Data#

9.9.1. Querying and Converting Polygon Data#

census_blocks_df = con.sql(
    "SELECT * EXCLUDE geom, ST_AsText(geom) as geometry FROM nyc_census_blocks"
).df()
census_blocks_df.head()

9.9.2. Transforming Census Blocks to GeoDataFrame#

census_blocks_gdf = leafmap.df_to_gdf(
    census_blocks_df, src_crs="EPSG:26918", dst_crs="EPSG:4326"
)
census_blocks_gdf.head()

9.9.3. Creating a Basic Polygon Map#

m = leafmap.Map(style="liberty")
m.add_vector(census_blocks_gdf, name="Census Blocks")
m

9.9.4. Customizing Polygon Symbology#

m = leafmap.Map(style="liberty")
paint = {
    "fill-color": "#ff0000",
    "fill-opacity": 0.5,
    "fill-outline-color": "#ffffff",
}
m.add_vector(census_blocks_gdf, layer_type="fill", paint=paint, name="Census Blocks")
m

9.9.5. Creating Choropleth Maps#

m = leafmap.Map(style="positron")
m.add_data(census_blocks_gdf, column="POPN_TOTAL")
m

9.9.6. Creating 3D Extrusion Maps#

m = leafmap.Map(
    style="positron", pitch=60, bearing=73.5, center=(-73.923449, 40.694178), zoom=11
)
m.add_data(
    census_blocks_gdf,
    column="POPN_TOTAL",
    cmap="coolwarm",
    extrude=True,
    fit_bounds=False,
)
m

9.10. Key Takeaways#

9.11. Exercises#

9.11.1. Exercise 1: Basic Point Visualization#

9.11.2. Exercise 2: Attribute-Based Filtering and Visualization#

9.11.3. Exercise 3: Line Network Visualization#

9.11.4. Exercise 4: Basic Polygon Visualization#

9.11.5. Exercise 5: Choropleth Mapping#

9.11.6. Exercise 6: Custom Choropleth Color Schemes#

9.11.7. Exercise 7: 3D Extrusion Visualization#

9.11.8. Exercise 8: Multi-Layer Visualization#

9.11.9. Exercise 9: Spatial Query Visualization#

9.11.10. Exercise 10: Custom Analysis and Visualization Pipeline#