Skip to content

sliding delaunay trianglessยค

delaunay triangles of random data.

%%
    import scipy.spatial, nbconvert_a11y, matplotlib.pyplot, nbconvert_a11y.table

    points = DataFrame(numpy.random.randn(20, 2), None, list("xy"))
    delaunay = scipy.spatial.Delaunay(points)

    def random_frame(*args, **kwargs):
        return bs4.BeautifulSoup(
            pandas.DataFrame(
                index=pandas.RangeIndex(random.randint(4, 20)), 
                columns=pandas.RangeIndex(random.randint(4, 20))
            ).fillna("")._repr_html_(),
            features="lxml"
        ).table


    df = DataFrame(index=pandas.MultiIndex.from_arrays(delaunay.simplices.T, names=list("abc")))

    df = df.assign(
        ax=df.index.get_level_values(0).map(lambda x: points.values[x, 0]).values,
        ay=df.index.get_level_values(0).map(lambda x: points.values[x, 1]).values,
        bx=df.index.get_level_values(1).map(lambda x: points.values[x, 0]).values,
        by=df.index.get_level_values(1).map(lambda x: points.values[x, 1]).values,
        cx=df.index.get_level_values(2).map(lambda x: points.values[x, 0]).values,
        cy=df.index.get_level_values(2).map(lambda x: points.values[x, 1]).values,
    )

    agg = points.agg("min max".split())
    agg.loc["diff"] = tuple(agg.iloc[::].diff().iloc[1])
    style = nbconvert_a11y.table.get_style_from_items(agg.T)

    df = df.assign(table=df.ax.apply(random_frame).values)
import scipy.spatial, nbconvert_a11y, matplotlib.pyplot, nbconvert_a11y.table

points = DataFrame(numpy.random.randn(20, 2), None, list("xy"))
delaunay = scipy.spatial.Delaunay(points)

def random_frame(*args, **kwargs):
    return bs4.BeautifulSoup(
        pandas.DataFrame(
            index=pandas.RangeIndex(random.randint(4, 20)), 
            columns=pandas.RangeIndex(random.randint(4, 20))
        ).fillna("")._repr_html_(),
        features="lxml"
    ).table


df = DataFrame(index=pandas.MultiIndex.from_arrays(delaunay.simplices.T, names=list("abc")))

df = df.assign(
    ax=df.index.get_level_values(0).map(lambda x: points.values[x, 0]).values,
    ay=df.index.get_level_values(0).map(lambda x: points.values[x, 1]).values,
    bx=df.index.get_level_values(1).map(lambda x: points.values[x, 0]).values,
    by=df.index.get_level_values(1).map(lambda x: points.values[x, 1]).values,
    cx=df.index.get_level_values(2).map(lambda x: points.values[x, 0]).values,
    cy=df.index.get_level_values(2).map(lambda x: points.values[x, 1]).values,
)

agg = points.agg("min max".split())
agg.loc["diff"] = tuple(agg.iloc[::].diff().iloc[1])
style = nbconvert_a11y.table.get_style_from_items(agg.T)

df = df.assign(table=df.ax.apply(random_frame).values)
%%

    table = df.table(
        caption="a table of tables with randoms delaunay triangles. scroll the table to fill in the triangles.", id="tri"
    ).checkbox({
        ("toggle delaunay view", True): 
```css
@property ---s {
    syntax: "<percentage>";
    initial-value: 0%;
    inherits: true;
}
@property ---r {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: true;
}
width: var(--wu); height: var(--hu);
thead, tfoot {
    display: none;
}
transform: translateY(-50%);
&amp; &gt; tbody {
    width: calc(var(--w) * var(--u)); height: calc(var(--h) * var(--u));
    display: block;
    position: relative;
    overflow: auto;
    padding: 100px;
    resize: both;
    &amp; &gt; tr {
        display: block;
        position: sticky;
        top: 0; left: 0;
        ---ax: calc(var(--wu) * ((var(--ax) - var(--x-min)) / var(--x-diff)));
        ---ay: calc(var(--hu) * ((var(--ay) - var(--y-min)) / var(--y-diff)));
        ---bx: calc(var(--wu) * ((var(--bx) - var(--x-min)) / var(--x-diff)));
        ---by: calc(var(--hu) * ((var(--by) - var(--y-min)) / var(--y-diff)));
        ---cx: calc(var(--wu) * ((var(--cx) - var(--x-min)) / var(--x-diff)));
        ---cy: calc(var(--hu) * ((var(--cy) - var(--y-min)) / var(--y-diff)));
        --c: calc(255 * (var(--cy) - var(--ay-min)) / var(--ay-diff));
        background: unset;
        --fr: calc((var(--cx) - var(--cx-min)) / var(--cx-diff));
        --r: calc(var(--fr) * 90deg);
        &amp;&gt;th, &amp;&gt;td:not(:last-of-type) {
            display: none;
        }
        width: calc(var(--w) * var(--u)); height: calc(var(--h) * var(--u));
        clip-path: unset;
        clip-path: polygon(var(---ax) var(---ay), var(---bx) var(---by), var(---cx) var(---cy), var(---ax) var(---ay));
        ---x: calc((var(---ax) + var(---bx) + var(---cx)) / 3);
        ---y: calc((var(---ay) + var(---by) + var(---cy)) / 3);
        &amp;&gt;td:last-of-type {
            display: block;
            ---c: rgba(var(--c), calc(255 - var(--c)), 0, .8);
            transform-origin: 50% 50%;
            transform: translate(-50%, -50%) translate(var(---x), var(---y)) rotate(var(--r)) scale(50%);
            &amp; &gt; table {
                th {display: none;}
                width: calc(var(--w) * var(--u)); height: calc(var(--h) * var(--u));
                td {
                    border: solid 4px;
                }
            }
        }
    }
}
```        
    })

    table.html.table.attrs["style"] += style
    table.html.table.caption.clear()
    table
a table of tables with randoms delaunay triangles. scroll the table to fill in the triangles.
a b c ax ay bx by cx cy table
17 14 16 0.973 2.026 1.148 0.399 1.237 0.261
0 1 2 3 4 5 6 7 8
0
1
2
3
4
5
6
7
8
9
10
11
12
2 14 17 0.524 0.635 1.148 0.399 0.973 2.026
0 1 2 3 4
0
1
2
3
4
5
6
7
8
9
4 2 17 -0.084 0.898 0.524 0.635 0.973 2.026
0 1 2 3 4 5 6 7 8 9 10 11 12
0
1
2
3
4
5
6
12 4 17 -0.752 0.891 -0.084 0.898 0.973 2.026
0 1 2 3 4 5 6 7 8 9 10
0
1
2
3
4
5
6
7
8
3 18 16 0.736 -0.882 1.153 -1.047 1.237 0.261
0 1 2 3 4 5 6 7 8 9 10 11 12 13
0
1
2
3
4
5
6
7
3 19 18 0.736 -0.882 -0.674 -1.425 1.153 -1.047
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
5 14 2 0.756 0.427 1.148 0.399 0.524 0.635
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
14 5 16 1.148 0.399 0.756 0.427 1.237 0.261
0 1 2 3 4 5 6 7 8 9
0
1
2
3
4
5
6
7
8
9
10
11
12
5 3 16 0.756 0.427 0.736 -0.882 1.237 0.261
0 1 2 3 4 5 6 7 8
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3 5 6 0.736 -0.882 0.756 0.427 0.169 0.001
0 1 2 3 4 5 6 7 8 9 10
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
19 8 15 -0.674 -1.425 -0.748 -0.374 -1.925 -0.414
0 1 2 3 4
0
1
2
3
0 12 1 -0.292 0.817 -0.752 0.891 -0.498 0.765
0 1 2 3 4 5 6 7 8 9 10 11 12 13
0
1
2
3
4
5
6
7
8
0 4 12 -0.292 0.817 -0.084 0.898 -0.752 0.891
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
4 13 2 -0.084 0.898 0.162 0.255 0.524 0.635
0 1 2 3 4 5 6 7 8 9
0
1
2
3
4
5
6
7
8
9
10
11
13 5 2 0.162 0.255 0.756 0.427 0.524 0.635
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0
1
2
3
4
5
6
7
8
9
10
5 13 6 0.756 0.427 0.162 0.255 0.169 0.001
0 1 2 3 4 5 6 7
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
11 3 6 -0.192 -0.741 0.736 -0.882 0.169 0.001
0 1 2 3 4 5 6 7 8 9 10
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
3 11 19 0.736 -0.882 -0.192 -0.741 -0.674 -1.425
0 1 2 3 4 5 6 7 8 9 10
0
1
2
3
4
5
6
7
8
9
10
11
12
13
11 8 19 -0.192 -0.741 -0.748 -0.374 -0.674 -1.425
0 1 2 3 4 5 6 7 8 9
0
1
2
3
4
5
10 12 15 -0.697 0.243 -0.752 0.891 -1.925 -0.414
0 1 2 3 4 5 6 7 8 9
0
1
2
3
4
5
6
7
8
9
10
11
12
8 10 15 -0.748 -0.374 -0.697 0.243 -1.925 -0.414
0 1 2 3 4 5 6 7 8 9 10 11
0
1
2
3
4
5
6
12 10 1 -0.752 0.891 -0.697 0.243 -0.498 0.765
0 1 2 3 4 5 6 7 8 9 10
0
1
2
3
4
5
6
7
8
9
10
0 9 4 -0.292 0.817 -0.233 0.347 -0.084 0.898
0 1 2 3
0
1
2
3
9 13 4 -0.233 0.347 0.162 0.255 -0.084 0.898
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
0
1
2
3
4
5
6
7
8
9
10
11
9 0 1 -0.233 0.347 -0.292 0.817 -0.498 0.765
0 1 2 3 4 5 6 7 8 9 10 11
0
1
2
3
4
5
6
7
8
9
10
11
12
10 9 1 -0.697 0.243 -0.233 0.347 -0.498 0.765
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
0
1
2
3
13 7 6 0.162 0.255 -0.205 0.172 0.169 0.001
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
9 7 13 -0.233 0.347 -0.205 0.172 0.162 0.255
0 1 2 3 4 5 6 7 8 9 10 11
0
1
2
3
4
7 11 6 -0.205 0.172 -0.192 -0.741 0.169 0.001
0 1 2 3 4 5 6 7
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
11 7 8 -0.192 -0.741 -0.205 0.172 -0.748 -0.374
0 1 2 3 4
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
7 10 8 -0.205 0.172 -0.697 0.243 -0.748 -0.374
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0
1
2
3
4
7 9 10 -0.205 0.172 -0.233 0.347 -0.697 0.243
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
min -0.752 -1.425 -0.752 -1.425 -1.925 -1.425 nan
max 1.148 2.026 1.153 0.898 1.237 2.026 nan
diff 1.900 3.451 1.905 2.323 3.162 3.451 nan
%%
compare with matplotlib, the mpl point are rotated to be congruent with table above.

    matplotlib.pyplot.triplot(delaunay.points[:, 0], delaunay.points[:, 1], delaunay.simplices)
    points.plot.scatter(*"xy", ax=matplotlib.pyplot.gca(), color="red")
    matplotlib.pyplot.gca().invert_yaxis()

compare with matplotlib, the mpl point are rotated to be congruent with table above.

matplotlib.pyplot.triplot(delaunay.points[:, 0], delaunay.points[:, 1], delaunay.simplices)
points.plot.scatter(*"xy", ax=matplotlib.pyplot.gca(), color="red")
matplotlib.pyplot.gca().invert_yaxis()
No description has been provided for this image
%%

```css
@property ---s {
    syntax: "<percentage>";
    initial-value: 0%;
    inherits: true;
}
@property ---r {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: true;
}

#tri {
    --w: 600; --h: 400; --u: 1px;
    --wu: calc(var(--w) * var(--u)); --hu: calc(var(--h) * var(--u));
    display: block;
    max-height: calc(2 * var(--hu));
    tbody {
    overflow: auto;
    }
    padding: 100px;
}
```