Master geographic and mapping visualizations with GeoViews. Use this skill when creating interactive maps, visualizing point/polygon/line geographic data, building choropleth maps, performing spatial analysis (joins, buffers, proximity), working with coordinate reference systems, or integrating tile providers and basemaps.
Creates interactive maps and performs spatial analysis with GeoViews and GeoPandas.
npx claudepluginhub uw-ssec/rse-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Master geographic and mapping visualizations with GeoViews and spatial data handling. This skill covers creating interactive maps, analyzing geographic data, and visualizing spatial relationships.
GeoViews extends HoloViews with geographic support:
import geoviews as gv
import geopandas as gpd
from geoviews import tile_providers as gvts
# Load geographic data
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# Basic map visualization
world_map = gv.Polygons(world, vdims=['name', 'pop_est']).opts(
title='World Population',
height=600,
width=800,
tools=['hover']
)
# Add tile layer background
tiled = gvts.ESRI.apply.opts(
alpha=0.4,
xaxis=None,
yaxis=None
) * world_map
# Create point features
cities_data = {
'city': ['New York', 'Los Angeles', 'Chicago'],
'latitude': [40.7128, 34.0522, 41.8781],
'longitude': [-74.0060, -118.2437, -87.6298],
'population': [8337000, 3990456, 2693976]
}
cities_gdf = gpd.GeoDataFrame(
cities_data,
geometry=gpd.points_from_xy(cities_data['longitude'], cities_data['latitude']),
crs='EPSG:4326'
)
# Visualize points
points = gv.Points(cities_gdf, kdims=['longitude', 'latitude'], vdims=['city', 'population'])
points = points.opts(
size=gv.dim('population').norm(min=5, max=50),
color='red',
tools=['hover', 'box_select']
)
# With tile background
map_with_points = gvts.CartoDEM.apply.opts(alpha=0.5) * points
# Color regions by data value
choropleth = gv.Polygons(world, vdims=['name', 'pop_est']).opts(
cmap='viridis',
color=gv.dim('pop_est').norm(),
colorbar=True,
height=600,
width=900,
tools=['hover']
)
# Add interactivity
choropleth = choropleth.opts(
hover_fill_color='red',
hover_fill_alpha=0.5
)
from holoviews import streams
# Create selectable map
selectable_map = gv.Polygons(world).opts(
tools=['box_select', 'tap'],
selection_fill_color='red',
nonselection_fill_alpha=0.2
)
# Stream for selection
selection_stream = streams.Selection1D()
def get_selected_data(index):
if index:
return world.iloc[index[0]]
return None
# Get info about selected region
selected_info = hv.DynamicMap(
lambda index: hv.Text(0, 0, str(get_selected_data(index))),
streams=[selection_stream]
)
# Multiple layers
terrain = gvts.Stamen.Terrain.apply.opts(alpha=0.3)
points = gv.Points(cities_gdf, kdims=['longitude', 'latitude'])
lines = gv.Lines(routes_gdf, kdims=['longitude', 'latitude'])
# Compose layers
map_composition = terrain * lines * points
# Faceted geographic display
faceted_maps = gv.Polygons(world, vdims=['name', 'continent']).facet('continent')
# Hexbin aggregation for point data
hexbin = gv.HexTiles(cities_gdf).opts(
cmap='viridis',
colorbar=True,
height=600,
width=800
)
# With tile background
map_hexbin = gvts.CartoDEM.apply.opts(alpha=0.4) * hexbin
# Combine different geographic layers
points_gdf = gpd.GeoDataFrame(
cities_data,
geometry=gpd.points_from_xy(cities_data['longitude'], cities_data['latitude']),
crs='EPSG:4326'
)
regions_gdf = gpd.read_file('regions.geojson')
# Spatial join: which cities are in which regions
joined = gpd.sjoin(points_gdf, regions_gdf, how='left', predicate='within')
# Visualize result
joined_map = gv.Points(joined, kdims=['longitude', 'latitude']) * \
gv.Polygons(regions_gdf)
from shapely.geometry import Point
# Create buffer zones
buffered = cities_gdf.copy()
buffered['geometry'] = buffered.geometry.buffer(1.0) # 1 degree
# Visualize buffered regions
buffers = gv.Polygons(buffered).opts(fill_alpha=0.3)
points = gv.Points(cities_gdf)
proximity_map = gvts.CartoDEM.apply.opts(alpha=0.3) * buffers * points
# Calculate distances between cities
from shapely.geometry import LineString
routes = []
for i in range(len(cities_gdf) - 1):
start = cities_gdf.geometry.iloc[i]
end = cities_gdf.geometry.iloc[i + 1]
route = LineString([start, end])
distance = start.distance(end)
routes.append({'geometry': route, 'distance': distance})
routes_gdf = gpd.GeoDataFrame(routes, crs='EPSG:4326')
# Visualize routes
route_lines = gv.Lines(routes_gdf, vdims=['distance']).opts(
color=gv.dim('distance').norm(),
cmap='plasma'
)
# Available tile providers
from geoviews import tile_providers as gvts
# Different styles
openstreetmap = gvts.OpenStreetMap.Mapnik
satellite = gvts.ESRI.WorldImagery
terrain = gvts.Stamen.Terrain
toner = gvts.Stamen.Toner
# Use with visualization
map_with_osm = gvts.OpenStreetMap.Mapnik * gv.Points(cities_gdf)
# Custom styling
base_map = gvts.CartoDEM.apply.opts(
alpha=0.5,
xaxis=None,
yaxis=None
)
# Always specify and manage CRS
gdf = gpd.read_file('data.geojson')
print(gdf.crs)
# Reproject if necessary
gdf_projected = gdf.to_crs('EPSG:3857') # Web Mercator
# When creating GeoDataFrame
gdf = gpd.GeoDataFrame(
data,
geometry=gpd.points_from_xy(lon, lat),
crs='EPSG:4326' # WGS84
)
# Use rasterization for dense point clouds
from holoviews.operation.datashader import rasterize
points = gv.Points(large_gdf, kdims=['x', 'y'])
rasterized = rasterize(points)
# Use tile-based rendering for massive datasets
# Consider breaking into GeoJSON tiles
# Combine multiple interaction tools
map_viz = gv.Polygons(gdf).opts(
tools=['hover', 'box_select', 'tap'],
hover_fill_color='yellow',
hover_fill_alpha=0.2,
selection_fill_color='red'
)
# Add complementary visualizations
statistics = hv.Text(0, 0, '') # Update based on selection
map_and_stats = hv.Column(map_viz, statistics)
# Use perceptually uniform colormaps
from colorcet import cm
map_viz = gv.Polygons(gdf, vdims=['value']).opts(
color=gv.dim('value').norm(),
cmap=cm['viridis'],
colorbar=True,
clim=(vmin, vmax)
)
def create_map_dashboard(layers_dict):
base_map = gvts.CartoDEM.apply.opts(alpha=0.4)
layers = [gv.Polygons(layers_dict[name]) for name in layers_dict]
return base_map * hv.Overlay(layers)
from holoviews import DynamicMap, streams
filter_stream = streams.Stream.define('filter', year=2020)
def update_map(year):
filtered_gdf = world[world['year'] == year]
return gv.Polygons(filtered_gdf, vdims=['name', 'value'])
dmap = DynamicMap(update_map, streams=[filter_stream])
def create_clustered_map(points_gdf, zoom_levels=[1, 5, 10, 20]):
# Use hexbin for aggregation at different scales
aggregated = gv.HexTiles(points_gdf, aggregation='count')
return aggregated.opts(responsive=True)
.hvplot(geo=True)gdf.is_valid.all()gdf.geometry.simplify(tolerance)Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.