Applying Color Palettes to Layers with `fc` and `ec` Parameters in Prettymaps: A Complete Guide
Use fc for fill colors and ec for edge colors in your style dictionary—supply a string for a single color or a list of colors to create a randomized palette effect.
Prettymaps renders stylized geographic maps by layering OpenStreetMap data with customizable visual properties. The fill color (fc) and edge color (ec) parameters control how each map layer appears, with special handling that lets you apply either uniform colors or randomized palettes to polygon features. This guide explains exactly how these parameters work according to the marceloprates/prettymaps source code.
How fc and ec Parameters Work in Prettymaps
The rendering pipeline delegates layer drawing to the plot_gdf helper function in [prettymaps/draw.py](https://github.com/marceloprates/prettymaps/blob/main/prettymaps/draw.py#L301-L371). This function inspects your style configuration and applies colors through Matplotlib's PolygonPatch.
The fc (Face/Fill Color) Parameter
The fc parameter accepts two distinct input types that trigger different behaviors:
- String value — A single color applied uniformly to all polygons in the layer
- List value — Treated as a color palette; each polygon receives a randomly selected color
The detection logic in [prettymaps/draw.py lines 341-361](https://github.com/marceloprates/prettymaps/blob/main/prettymaps/draw.py#L341-L361) implements this branching:
if (palette is None) and ("fc" in kwargs) and (type(kwargs["fc"]) != str):
palette = kwargs.pop("fc") # Extract list into palette variable
# Later in the rendering loop:
fc = kwargs["fc"] if "fc" in kwargs else np.random.choice(palette) if palette else None
When fc contains a list, Prettymaps calls np.random.choice(palette) for each polygon, producing varied, mosaic-like appearances ideal for urban building layers.
The ec (Edge Color) Parameter
The ec parameter controls polygon stroke color. Unlike fc, it accepts only string values and passes directly to Matplotlib without transformation. From [prettymaps/draw.py lines 52-58](https://github.com/marceloprates/prettymaps/blob/main/prettymaps/draw.py#L52-L58):
ec = kwargs["ec"] if "ec" in kwargs else None
If omitted, edges default to None (no visible stroke).
Two Ways to Define Color Palettes
Prettymaps supports equivalent syntax for palette definition—choose the style that fits your workflow.
Method 1: fc as a Color List
Pass your palette directly through the fc key:
style = {
"building": {
"fc": ["#FFC857", "#E9724C", "#C5283D"], # Randomized per building
"ec": "#2F3737",
"lw": 0.5,
}
}
Method 2: Dedicated palette Key
Use the explicit palette parameter for clearer intent:
style = {
"building": {
"palette": ["#FFC857", "#E9724C", "#C5283D"], # Same randomized effect
"ec": "#2F3737",
"lw": 0.5,
}
}
Both approaches yield identical rendering. The palette key exists purely for readability, as confirmed by the implementation extracting either into the same local palette variable.
Practical Code Examples
Fixed Single Colors
Apply uniform colors when you need consistency across a layer:
import prettymaps
style_fixed = {
"perimeter": {"fc": "#F2F4CB", "ec": "#2F3737", "lw": 1},
"water": {"fc": "#A1D6E2", "ec": "#2F3737", "lw": 0.5},
"building": {"fc": "#FFC857", "ec": "#2F3737", "lw": 0.5},
}
prettymaps.plot(
"Praça Ferreira do Amaral, Macau",
style=style_fixed,
save_as="macau_fixed.png"
)
This matches the basic fc usage demonstrated in the usage guide.
Randomized Color Palette
Create visual variety by supplying multiple fill colors:
style_palette = {
"building": {
"fc": ["#FFC857", "#E9724C", "#C5283D", "#481D24", "#255957"],
"ec": "#2F3737",
"lw": 0.3,
},
"green": {"fc": "#8FBC8F", "ec": "#2F3737"},
"water": {"fc": "#A1D6E2", "ec": "#2F3737"},
}
prettymaps.plot(
"Praça Ferreira do Amaral, Macau",
style=style_palette,
save_as="macau_palette.png"
)
The tutorial documentation showcases this pattern for the Macau building layer.
Combining Approaches
Mix fixed and palette-based layers in one style:
style_mixed = {
"perimeter": {"fc": "#F2F4CB", "ec": "#2F3737"}, # Single fill
"water": {"fc": "#A1D6E2", "ec": "#006994"}, # Single fill
"building": {
"palette": ["#E63946", "#F1FAEE", "#A8DADC", # Randomized fill
"#457B9D", "#1D3557"],
"ec": "#1D3557",
"lw": 0.4,
},
"road": {"fc": "#2B2D42", "ec": "#2F3737"},
}
prettymaps.plot(
"Bairro Alto, Lisbon",
style=style_mixed,
)
Parameter Reference Table
| Parameter | Type | Purpose | Example Values |
|---|---|---|---|
fc |
str or list[str] |
Fill color for polygons | "#FFC857" or ["#FFC857", "#E9724C"] |
palette |
list[str] |
Alternative fill palette syntax | ["#FFC857", "#E9724C", "#C5283D"] |
ec |
str |
Edge (stroke) color | "#2F3737" or "none" |
lw |
float |
Line width for edges | 0.5, 1.2 |
Where Palette Logic Lives in the Source Code
Understanding the implementation helps debug unexpected rendering:
- Core rendering: [
prettymaps/draw.pylines 301-371](https://github.com/marceloprates/prettymaps/blob/main/prettymaps/draw.py#L301-L371) —plot_gdffunction - Palette detection: [
prettymaps/draw.pylines 341-361](https://github.com/marceloprates/prettymaps/blob/main/prettymaps/draw.py#L341-L361) — Type checking andnp.random.choiceinvocation - Edge color handling: [
prettymaps/draw.pylines 52-58](https://github.com/marceloprates/prettymaps/blob/main/prettymaps/draw.py#L52-L58) — Direct parameter pass-through
Summary
fccontrols fill colors: String for uniform color, list for randomized palette selectioneccontrols edge colors: Always a string, passed directly to Matplotlib- Two palette syntaxes:
fcas list or explicitpalettekey—functionally identical - Randomization happens per-polygon: Each building, park, or water body gets an independent color selection from your palette
- Layer configuration happens in style dictionaries: Pass to
prettymaps.plot()via thestyleparameter
Frequently Asked Questions
Can I use hex colors, RGB tuples, or named colors for fc and ec?
Prettymaps accepts any Matplotlib-compatible color specifier. Hex strings like "#FFC857", named colors like "crimson", and RGB tuples like (1, 0.2, 0.3) all work for both fc and ec. For palette lists, ensure all entries use consistent formats.
Why do my buildings all share the same color when I specified a palette?
Verify you're passing a list to fc, not a string with commas. Incorrect: "fc": "#FFC857,#E9724C" (single string). Correct: "fc": ["#FFC857", "#E9724C"] (actual Python list). Also check that you haven't accidentally included a string fc that prevents palette detection.
Does Prettymaps support gradients or continuous color scales?
No—the fc/palette system only supports discrete random selection from a defined list. For continuous coloring based on data values (e.g., building height), you would need to pre-process your GeoDataFrame and use Matplotlib's native colormapping directly rather than Prettymaps' style dictionaries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →