Voronoi diagram or similar in Altair #2727
Replies: 4 comments 8 replies
-
There are these two examples, not sure how generally applicable they are:
You can see the code by clicking to edit the cell the map is in. There is also a voronoi transformation in Vega https://vega.github.io/vega/docs/transforms/voronoi/ (but not VegaLite I think), which I believe is used for interactions in VegaLite that are using |
Beta Was this translation helpful? Give feedback.
-
Thanks a lot @joelostblom! I had seen the Observable notebooks but not the Vega discussion. This functionality is perfect if there is a way to fill in the cells with a color (other than in the context of a geographic shape). Do you think asking if there is a way to do that would be appropriate on the Vega GitHub page? |
Beta Was this translation helpful? Give feedback.
-
I recently re-discovered the encoding channel import numpy as np
from scipy.spatial import Voronoi
import pandas as pd
from shapely.ops import orient
from shapely import geometry
import shapely
import altair as alt
# make up data points add 4 distant dummy points and compute Voronoi tesselation
df_pts = pd.DataFrame(
{"u": [0.1, 0.9, 0.1, 0.9, 0.5], "v": [0.1, 0.1, 0.9, 0.9, 0.5], "z": list("abcde")}
)
df_pts_extended = pd.concat(
(
df_pts,
pd.DataFrame(
[[999, 999], [-999, 999], [999, -999], [-999, -999]], columns=["u", "v"]
),
),
ignore_index=True,
)
points = df_pts_extended[["u", "v"]].values
vor = Voronoi(points)
# polygonize voronoi regions as geojson features, add 'tessel' index key for color
vals = []
for ix, region in enumerate(vor.regions):
if not -1 in region:
polygon = [vor.vertices[i] for i in region]
geompol = geometry.Polygon(polygon)
if not geompol.is_empty:
if geompol.exterior.is_ccw:
geompol = orient(geompol, -1)
feature = {
"type": "Feature",
"properties": {},
"geometry": shapely.geometry.mapping(geompol),
}
ixs=vor.point_region[ix-1] # trial
vals.append({
"geo": feature,
"tessel": df_pts_extended.iloc[ixs].z # trial
})
# set the fit/extent range of axes, must be an array with a geom
xmin, xmax = 0, 1
ymin, ymax = 0, 1
extent = geometry.Polygon(
[(xmax, ymax), (xmax, ymin), (xmin, ymin), (xmin, ymax), (xmax, ymax)]
)
fit = [shapely.geometry.mapping(extent)]
voronoi = alt.Data(name="vals", values=vals)
c_vor = (
alt.Chart(voronoi)
.mark_geoshape(clip=True, tooltip=True, opacity=0.3, stroke="black")
.encode(shape="geo:G", color="tessel:N")
)
c_pts = (
alt.Chart(df_pts)
.mark_circle(clip=True, color="orange", tooltip=True, size=100, opacity=1)
.encode(latitude="u:Q", longitude="v:Q", color="z:N")
)
(c_vor + c_pts).project(
type="identity", reflectY=True, fit=fit
) I tried to connect the computed regions to the value in the |
Beta Was this translation helpful? Give feedback.
-
Pinging this discussion again, would there be any interest among maintainers in adding a mark or transformation that produces a vornoi tessellation, without the need for scipy calculations and geo-wizardry? My research group would benefit from such functionality, and I'd be interested in figuring out how to contribute it myself, especially since the algorithm's already in Vega. |
Beta Was this translation helpful? Give feedback.
-
This is probably more of a question for Vega-Lite, but I thought I would try here first.
Is there any natural way (even with most of the work happening outside of Altair) to make a chart like a solid version of this one: Open the Chart in the Vega Editor?
I'm trying to illustrate the decision boundary for a logistic regression classifier. Here what I did was just artificially make a grid of points and color them using the classifier.
Even a simpler picture like where there is a diagonal line in the xy-plane and I want the half-plane on one side of the line to be colored one way and the half-plane on the other side to be colored a different way, I don't think I would know how to produce in Altair. (If it were a vertical line or a horizontal line, I think I could accomplish this using
mark_rect
.)Here is an example of the type of end result I would like using Matplotlib.
If you think I should instead ask at Vega-Lite, is there any information you think I should add to make my question more clear?
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions