from pyobsplot import Obsplot, Plot
import geopandas as gpd
import pandas as pd
# Load US counties from TopoJson with geopandas
counties = gpd.read_file("data/us-counties-10m.json", layer="counties")
counties["id"] = pd.to_numeric(counties["id"])
# Merge unemployment values
unemployment = pd.read_csv("data/us-county-unemployment.csv")
counties = pd.merge(counties, unemployment.loc[:, ("id", "rate")], on="id", how="left")
# Convert geodataframe to GeoJson
counties = counties.to_json()
# Map
Plot.plot(
{
"marks": [Plot.geo(counties, {"fill": js("(d) => d.properties.rate")})],
"projection": "albers-usa",
"color": {
"type": "quantile",
"n": 8,
"scheme": "blues",
"label": "Unemployment (%)",
"legend": True,
},
}
)Mapping and spatial data
Geo mark
The Geo mark allows to draw geographic features such as points, lines and polygons. These marks data are passed as GeoJSON.
This allows to create choropleth maps such as the following:
Of course other marks can be used in conjunction with geo marks. This example represents the density of Walmarts supermarkets and is taken from the Mapping notebook.
# Load US states from TopoJson with geopandas and convert to GeoJson
states = gpd.read_file("data/us-counties-10m.json", layer="states").to_json()
nation = gpd.read_file("data/us-counties-10m.json", layer="nation").to_json()
walmarts = pd.read_csv("data/walmarts.tsv", sep="\t")
Plot.plot(
{
"marks": [
Plot.density(
walmarts,
{"x": "longitude", "y": "latitude", "bandwidth": 12, "fill": "density"},
),
Plot.dot(
walmarts,
{"x": "longitude", "y": "latitude", "r": 1, "fill": "currentColor"},
),
Plot.geo(states, {"strokeOpacity": 0.3}),
Plot.geo(nation),
],
"projection": "albers",
"color": {"scheme": "blues"},
}
)Raster mark
The Raster mark creates an image from spatial data.
Plot allows to do different type of spatial interpolations, such as nearest, which draws voronoi cells around values:
import polars as pl
ca55 = pl.read_csv("data/ca55-south.csv")
def flare_map(interpolation):
return Plot.plot(
{
"x": {"axis": None},
"y": {"axis": None},
"inset": 10,
"marginBottom": 2,
"height": 500,
"color": {"type": "diverging"},
"marks": [
Plot.raster(
ca55,
{
"x": "LONGITUDE",
"y": "LATITUDE",
"fill": "MAG_IGRF90",
"interpolate": interpolation,
},
),
Plot.frame(),
],
}
)
flare_map("nearest")Or the more recent random walk interpolation:
flare_map("random-walk")