SHAPELY_PLOT
Renders one or more WKT geometries to a 2D plot and returns a base64-encoded PNG image string suitable for display in Excel.
The function parses geometry inputs, draws points/lines/polygons with optional color and transparency, then exports the figure as an inline image URI.
Transparency is controlled by an alpha parameter in the interval:
0 \leq \alpha \leq 1
Excel Usage
=SHAPELY_PLOT(geometries, color, alpha)
geometries(list[list], required): List of WKT strings to plot.color(str, optional, default: null): Color of the plot elements.alpha(float, optional, default: 0.5): Transparency (0.0 to 1.0).
Returns (str): Base64 encoded PNG image.
Example 1: Plot a line
Inputs:
| geometries |
|---|
| LINESTRING (0 0, 2 2, 4 1) |
Excel formula:
=SHAPELY_PLOT(LINESTRING (0 0, 2 2, 4 1))
Expected output:
"chart"
Example 2: Plot mixed geometries
Inputs:
| geometries | alpha |
|---|---|
| POINT (0 0),LINESTRING (0 0, 1 2),POLYGON ((2 0, 3 0, 3 1, 2 1, 2 0)) | 0.6 |
Excel formula:
=SHAPELY_PLOT(POINT (0 0),LINESTRING (0 0, 1 2),POLYGON ((2 0, 3 0, 3 1, 2 1, 2 0)), 0.6)
Expected output:
"chart"
Example 3: Plot a square
Inputs:
| geometries |
|---|
| POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)) |
Excel formula:
=SHAPELY_PLOT(POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)))
Expected output:
"chart"
Example 4: Plot points
Inputs:
| geometries | color |
|---|---|
| POINT (0 0),POINT (1 1) | red |
Excel formula:
=SHAPELY_PLOT(POINT (0 0),POINT (1 1), "red")
Expected output:
"chart"
Python Code
import sys
import matplotlib
if sys.platform == "emscripten":
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from shapely import wkt
import io
import base64
import numpy as np
def shapely_plot(geometries, color=None, alpha=0.5):
"""
Plot geometries and return an image.
See: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html
This example function is provided as-is without any representation of accuracy.
Args:
geometries (list[list]): List of WKT strings to plot.
color (str, optional): Color of the plot elements. Default is None.
alpha (float, optional): Transparency (0.0 to 1.0). Default is 0.5.
Returns:
str: Base64 encoded PNG image.
"""
try:
# Helper to flatten inputs
def flatten(x):
if isinstance(x, list):
out = []
for item in x:
out.extend(flatten(item))
return out
return [x]
raw_list = flatten(geometries)
wkt_list = [str(s) for s in raw_list if s and isinstance(s, str)]
if not wkt_list:
return "Error: No geometries provided"
# Parse geometries
geoms = []
for s in wkt_list:
try:
geoms.append(wkt.loads(s))
except:
pass
if not geoms:
return "Error: No valid geometries found"
# Setup plot
plt.clf()
fig, ax = plt.subplots(figsize=(6, 6))
# Default colors cycle if not provided
prop_cycle = plt.rcParams['axes.prop_cycle']
colors = prop_cycle.by_key()['color']
# Plot helper
def plot_geom(g, c=None):
if g.is_empty: return
if g.geom_type == 'Point':
x, y = g.x, g.y
ax.plot(x, y, 'o', color=c, alpha=alpha)
elif g.geom_type == 'LineString':
x, y = g.xy
ax.plot(x, y, '-', color=c, alpha=alpha, linewidth=2)
elif g.geom_type == 'Polygon':
# Plot exterior
x, y = g.exterior.xy
ax.plot(x, y, '-', color=c, alpha=1.0) # Boundary solid
ax.fill(x, y, color=c, alpha=alpha) # Fill transparent
# Plot holes
for interior in g.interiors:
xi, yi = interior.xy
ax.plot(xi, yi, '-', color='w', linewidth=1) # Hole boundary
elif g.geom_type.startswith('Multi') or g.geom_type == 'GeometryCollection':
for part in g.geoms:
plot_geom(part, c)
for i, g in enumerate(geoms):
c = color if color else colors[i % len(colors)]
plot_geom(g, c)
ax.set_aspect('equal')
ax.grid(True, linestyle=':', alpha=0.6)
# Determine bounds logic? matplotlib handles auto-scaling usually.
# Return image
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight')
plt.close(fig)
buf.seek(0)
img_str = base64.b64encode(buf.read()).decode('utf-8')
return f"data:image/png;base64,{img_str}"
except Exception as e:
return f"Error: {str(e)}"Online Calculator
List of WKT strings to plot.
Color of the plot elements.
Transparency (0.0 to 1.0).