🔍 Extract Field Names Containing 'type' (Integer Fields Without Domain) from GDB Using ArcPy

  ⚙️ How the Script Works 🗂️ Geodatabase Setup The script starts by pointing to a target File Geodatabase (.gdb) and initializing a CSV ...

Saturday, April 19, 2025

Post #7: Create Interactive Maps with Folium and Plotly

 

Title: Make Your Maps Interactive with Folium and Plotly in Python


📍Introduction

Static maps are great, but sometimes you need an interactive map. With Folium and Plotly, you can create maps that users can zoom, pan, and interact with in a web browser. These maps are perfect for dashboards, data exploration, or interactive reports.

In this post, we'll cover:

  • Folium: Creating interactive maps with Leaflet.js (perfect for quick web maps)

  • Plotly: Advanced visualizations with interactivity for geospatial data


🧰 Step 1: Install Folium and Plotly

First, you need to install the libraries:

bash
pip install folium plotly

🗺️ Step 2: Create an Interactive Map with Folium

Folium is based on Leaflet.js, a popular JavaScript library for creating interactive maps. It’s extremely easy to use, and you can embed your maps in websites with just a few lines of code.

python
import folium # Create a base map m = folium.Map(location=[21.4225, 39.8262], zoom_start=13) # Coordinates of Mecca # Add a marker (for example, a well location) folium.Marker([21.4225, 39.8262], popup="Water Well").add_to(m) # Save to HTML m.save("output/mecca_map.html")

This will generate an interactive map centered on Mecca with a marker on the specified coordinates. You can open the mecca_map.html file in your browser to interact with the map.


🧠 What Just Happened?

  • folium.Map() creates a map with an initial location and zoom level.

  • folium.Marker() adds a marker with a popup message to the map.

  • .save() exports the map as an HTML file that can be viewed in any browser.


📍 Step 3: Create Interactive Maps with Plotly

If you want advanced customization and more interactivity (like hover effects or zoomable choropleths), Plotly is your best friend.

python
import plotly.express as px import geopandas as gpd # Load a GeoDataFrame districts = gpd.read_file("data/districts.shp") # Plot with Plotly fig = px.choropleth(districts, geojson=districts.geometry, locations=districts.index, color="population", color_continuous_scale="Viridis", labels={"population": "Population"}) # Update map layout fig.update_geos(fitbounds="locations") fig.update_layout(title="Districts Population", geo=dict(showcoastlines=True)) # Show the interactive map fig.show()

This code creates an interactive choropleth map where the color of each district reflects its population.


🧠 What Just Happened?

  • px.choropleth() makes a choropleth map using GeoPandas geometries.

  • fig.update_geos() adjusts the map to fit your data, adding coastlines and other settings.

  • fig.show() opens the interactive map in your browser.


🌍 Step 4: Add Tooltips and Hover Effects with Plotly

You can also customize the hover tooltips to display additional information.

python
fig = px.choropleth(districts, geojson=districts.geometry, locations=districts.index, color="population", hover_name="district_name", hover_data=["area", "elevation"], color_continuous_scale="Viridis", labels={"population": "Population"}) fig.update_geos(fitbounds="locations") fig.update_layout(title="Districts Population", geo=dict(showcoastlines=True)) # Show the interactive map fig.show()

In this example:

  • hover_name="district_name": When you hover over a district, it shows the district's name.

  • hover_data=["area", "elevation"]: Displays additional information, like area and elevation, when hovering over each feature.


📍 Step 5: Save the Interactive Plotly Map as HTML

You can save your Plotly map as an interactive HTML file:

python
fig.write_html("output/interactive_districts_map.html")

This saves the interactive map to an HTML file that you can embed in a web page or share directly.


🧠 Why Use Folium & Plotly for Interactive Maps?

  • Folium is quick and easy for simple interactive maps, perfect for embedding into reports or websites.

  • Plotly provides more powerful visualizations with customizable features like hover effects, popups, and custom tooltips.

  • Interactivity: Let users zoom, pan, and explore your maps, making the data come alive.


🎯 Conclusion

Both Folium and Plotly are fantastic tools for adding interactivity to your maps. Whether you need something simple and quick or an advanced, customizable map, these libraries make it easy to add value to your geospatial projects.


📌 Next Up:

➡️ Post 8: Geospatial Data Analysis with Machine Learning in Python

Post #6: Adding Basemaps to Your Maps with Contextily & XYZ Tiles

 

Title: Add Stunning Basemaps to Your Python Maps with Contextily


📍Introduction

When you're plotting GIS data, the basemap can make a huge difference. Whether it’s satellite imagery, terrain, or streets, basemaps provide context to your spatial data, helping you communicate your analysis better.

In this post, we’ll show you how to easily integrate basemaps (like OpenStreetMap, Google Satellite, or Esri) into your maps using Contextily and XYZ tiles.


🧰 Step 1: Install Contextily

Contextily makes it super easy to add basemaps to your GeoPandas plots. First, install it using pip:

bash
pip install contextily

🗂️ Step 2: Load the Data

We’ll continue using the districts and wells data from previous posts. If you don’t have them, any polygon and point layers will work.

python
import geopandas as gpd import matplotlib.pyplot as plt import contextily as ctx # Load polygons and points districts = gpd.read_file("data/districts.shp") wells = gpd.read_file("data/water_wells.shp") # Ensure the CRS is the same districts = districts.to_crs("EPSG:4326") wells = wells.to_crs("EPSG:4326")

🌍 Step 3: Add a Basemap

Use the Contextily basemaps. We’ll overlay OpenStreetMap as the background for our plot.

python
fig, ax = plt.subplots(figsize=(12, 12)) # Plot your spatial data districts.plot(ax=ax, color='lightgreen', edgecolor='black') wells.plot(ax=ax, color='blue', markersize=20) # Add basemap ctx.add_basemap(ax, crs=districts.crs.to_string(), source=ctx.providers.OpenStreetMap.Mapnik) ax.set_title("Water Wells with Districts and OpenStreetMap Basemap", fontsize=14) plt.axis("off") plt.tight_layout() plt.show()

🧠 What Just Happened?

  • ctx.add_basemap() adds a base layer beneath your map.

  • crs=districts.crs.to_string() ensures the basemap aligns with your data’s CRS (Coordinate Reference System).

  • ctx.providers.OpenStreetMap.Mapnik selects the OpenStreetMap basemap style. You can change this to other basemaps, like Esri or Stamen.


📍 Step 4: Use Different Basemap Providers

Contextily provides many different basemaps. You can easily swap between them by choosing a different provider.

Here are some options:

  • Stamen Terrain

python
ctx.providers.Stamen.Terrain
  • Stamen Toner (Black & White)

python
ctx.providers.Stamen.Toner
  • Esri World Imagery (Satellite)

python
ctx.providers.Esri.WorldImagery
python
# Example: Add Esri Satellite Basemap ctx.add_basemap(ax, crs=districts.crs.to_string(), source=ctx.providers.Esri.WorldImagery)

🗺️ Step 5: Customize the Map Further

You can still apply your own styling to the GIS data even with the basemap in place. For example, you can adjust marker size, add labels, or change colors:

python
fig, ax = plt.subplots(figsize=(12, 12)) # Plot districts with custom style districts.plot(ax=ax, color='lightgreen', edgecolor='black') # Plot wells with custom marker size and color wells.plot(ax=ax, color='red', markersize=50) # Add Esri Satellite basemap ctx.add_basemap(ax, crs=districts.crs.to_string(), source=ctx.providers.Esri.WorldImagery) ax.set_title("Wells with Esri Satellite Basemap", fontsize=14) plt.axis("off") plt.tight_layout() plt.show()

💾 Step 6: Export the Map with Basemap

You can easily save the map with the basemap as a PNG or PDF:

python
fig.savefig("output/wells_districts_satellite_map.png", dpi=300) fig.savefig("output/wells_districts_satellite_map.pdf")

🧠 Why Add a Basemap?

  • Context: Gives viewers a reference point (like streets, satellite imagery, or terrain) for your spatial data.

  • Professional Quality: A basemap adds polish to your map, making it more suitable for presentations and reports.

  • Layer Flexibility: You can mix multiple basemaps with your own layers (e.g., roads over satellite imagery).


🎯 Conclusion

Integrating basemaps into your maps is easy with Contextily. Now you can create beautiful, informative maps with rich backgrounds like satellite imagery, streets, or terrain—perfect for reports, web applications, or just better data visualization.


📌 Next Up:

➡️ Post 7: Interactive Maps with Folium and Plotly

Post #5: Automating Map Exports for Each Feature in Python

 

Title: Automatically Export One Map per Feature Using Python & GeoPandas


📍Introduction

Ever had to manually export 100+ maps—one for each zone, district, or parcel?
Let’s stop doing it manually. With Python, you can loop through your features and save one map per feature as a PNG, PDF, or even a web map.

We’ll automate:

  • Filtering your layer

  • Plotting one feature at a time

  • Exporting maps with custom titles and names

Let’s build your own map production engine. 🛠️


🧰 Step 1: Load the Shapefiles

python
import geopandas as gpd import matplotlib.pyplot as plt import os # Load polygons (e.g., districts) and points (e.g., wells) districts = gpd.read_file("data/districts.shp") wells = gpd.read_file("data/water_wells.shp") # Make sure CRS matches districts = districts.to_crs("EPSG:4326") wells = wells.to_crs("EPSG:4326")

🗂️ Step 2: Create an Output Folder

python
output_folder = "output/maps" os.makedirs(output_folder, exist_ok=True)

🔁 Step 3: Loop Through Features and Export Maps

python
for idx, district in districts.iterrows(): district_name = district["district_name"] single_district = gpd.GeoDataFrame([district], crs=districts.crs) # Filter wells inside the district wells_in_district = wells[wells.within(district.geometry)] # Plot fig, ax = plt.subplots(figsize=(10, 10)) single_district.plot(ax=ax, color='lightgreen', edgecolor='black') wells_in_district.plot(ax=ax, color='blue', markersize=20) ax.set_title(f"Wells in {district_name}", fontsize=14) plt.axis("off") plt.tight_layout() # Save filename = os.path.join(output_folder, f"map_{district_name}.png") plt.savefig(filename, dpi=300) plt.close()

💡 Bonus: Clean Up Filenames

python
from slugify import slugify filename = os.path.join(output_folder, f"map_{slugify(district_name)}.png")

Install python-slugify with:

bash
pip install python-slugify

🧠 What Can You Use This For?

  • One PDF/PNG per municipality, parcel, plot, project area

  • Batch mapping for client reports

  • Export thematic maps for schools, wells, or zoning

  • Save per-feature maps to share on email, Google Drive, etc.


📌 Want to Go Further?

  • Add labels using plt.text()

  • Include basemaps using contextily

  • Create PDFs with PdfPages

  • Combine multiple maps into a dashboard layout with subplot2grid


🎯 Conclusion

Map production doesn’t need to be manual. With just a loop and some Python logic, you can export hundreds of clean, high-quality maps—customized for each feature.

This is how GIS automation adds real productivity to your workflow.


📌 Next Up:

➡️ Post 6: Add Basemaps to Your Maps with Contextily and XYZ Tiles

Post #4: Plotting and Styling GIS Data with Python

 

Title: Plot Beautiful Maps with Python: GeoPandas + Matplotlib Styling Tips


📍Introduction

Once you've loaded, joined, or filtered your GIS data, the next step is to visualize it. A good map tells the story at a glance—and Python gives you full control over how your map looks.

In this post, we'll cover:

  • Basic plotting with GeoPandas

  • Customizing colors, borders, legends, and labels

  • Exporting high-quality images for reports

Let’s turn spatial data into beautiful, readable maps.


🧰 Step 1: Load Your Layer

We’ll use a polygon and point layer example—like districts and wells.

python
import geopandas as gpd import matplotlib.pyplot as plt districts = gpd.read_file("data/districts.shp") wells = gpd.read_file("data/water_wells.shp") # Ensure CRS is the same districts = districts.to_crs("EPSG:4326") wells = wells.to_crs("EPSG:4326")

🗺️ Step 2: Basic Map Plot

python
districts.plot()

Now let’s customize it:

python
fig, ax = plt.subplots(figsize=(12, 10)) districts.plot(ax=ax, color='lightyellow', edgecolor='black') wells.plot(ax=ax, color='blue', markersize=10) ax.set_title("Water Wells in Districts", fontsize=16) plt.axis("off") plt.tight_layout() plt.show()

🎨 Step 3: Add Styling by Attribute

Color districts by population:

python
districts.plot(column='population', cmap='OrRd', legend=True, edgecolor='grey')

You can use other colormaps like "YlGnBu", "viridis", "plasma", "coolwarm", etc.


📍 Step 4: Add Labels to Features

Add district names:

python
for idx, row in districts.iterrows(): plt.text(row.geometry.centroid.x, row.geometry.centroid.y, row["district_name"], fontsize=8, ha='center', color='darkred')

💡 Use .centroid for polygons. For points, just use row.geometry.x, row.geometry.y.


🖼️ Step 5: Export the Map as Image

Save your map as PNG or PDF:

python
fig.savefig("output/districts_wells_map.png", dpi=300) fig.savefig("output/districts_wells_map.pdf")

💡 Bonus Styling Tips

  • Use alpha=0.5 to control transparency

  • Try markersize or linewidth to emphasize layers

  • Overlay multiple GeoDataFrames on the same ax for composite maps

  • Annotate features using ax.annotate()


🧠 Why Use Python for Mapping?

  • Generate maps automatically from any dataset

  • Create hundreds of maps in a loop (e.g., one per district)

  • Customize layouts for reports, posters, or dashboards

  • Integrate maps directly into data pipelines


🎯 Conclusion

With a few lines of code, you can build custom maps that are informative, beautiful, and ready for publication. No need to open a GIS interface every time—you now have a Python-powered map studio at your fingertips.


📌 Next Up:

➡️ Post 5: Automate Map Creation from Shapefiles in Bulk