Skip to content

finally, a 3d plot with axesยค

jump to the demo

from nbconvert_a11y.repr import get_table, new
from nbconvert_a11y.table import aria

df = DataFrame(numpy.random.randn(29, 4), columns= list("xyza"))
df = pandas.concat((df, Series([0]*4, list("xyza")).to_frame(29).T))
df.index = df.index.rename("position")

g = df.groupby([
    df[x].round(1) for x in df.columns 
]).apply(DataFrame)
g.index = g.index.rename(( "X", "Y", "Z", "A", "position"))
%%

css properties and 3d plot settings

    PROPERTIES =\
```text/css
@property --w {
    syntax: "<length>";
    initial-value: 600px;
    inherits: true;
}
@property --h {
    syntax: "<length>";
    initial-value: 400px;
    inherits: true;
}
@property --d {
    syntax: "<length>";
    initial-value: 400px;
    inherits: true;
}
@property --r {
    syntax: "<transform-function>";
    initial-value: scale(1);
    inherits: true;
}
@property ---r {
    syntax: "<transform-function>";
    initial-value: scale(1);
    inherits: true;
}
@property --t {
    syntax: "<time>";
    initial-value: 1.5s;
    inherits: true;
}
```

    DDD =\
```text/css
figure {
    --fg: white;
    --bg: black;
    margin: 100px;
    table, tbody, tr, th, td {
        transform-style: preserve-3d;
        transition: all var(--t) linear;
    }
    --p: 10in;
    table.ddd {
        width: var(--w); height: var(--h);
        position: relative;
        display: block;
        background: var(--bg);
        color: var(--fg);
        ---cx: calc((0 - var(---0-min)) / var(---0-diff) * var(--w));
        ---cy: calc((0 - var(---1-min)) / var(---1-diff) * var(--h));
        ---cz: calc((0 - var(---2-min)) / var(---2-diff) * var(--d));
        transform: var(--r);
        transform-origin: var(---cx) var(---cy) var(---cz);
        tbody {
            display: block;
            tr {
                opacity: .8;
                font-size: .2rem;
                &amp;:hover {
                    font-size: 1.1rem;
                }
                display: grid;
                background: unset !important;
                grid-template-columns: repeat(2, 1fr);
                grid-template-rows: repeat(2, 1fr);
                position: absolute;
                --dx: calc((var(--0) - var(---0-min)) / var(---0-diff) * var(--w));
                --dy: calc((var(--1) - var(---1-min)) / var(---1-diff) * var(--h));
                --dz: calc((var(--2) - var(---2-min)) / var(---2-diff) * var(--d));
                ---dx: calc((var(---0) - var(---0-min)) / var(---0-diff) * var(--w));
                ---dy: calc((var(---1) - var(---1-min)) / var(---1-diff) * var(--h));
                ---dz: calc((var(---2) - var(---2-min)) / var(---2-diff) * var(--d));
                --center: translate(-50%, -50%);
                transform:
                    translateX(var(--dx))
                    translateY(var(--dy))
                    translateZ(var(--dz))
                    var(---r)
                    var(--center)
                    ;
                th {
                    font-size: 1rem;

                    &amp;:nth-of-type(1) {
                        color: red;
                        position: absolute;
                        transform: 
                            var(--r)
                            translateX(calc(var(---dx) - var(--dx)))
                            translateY(calc(var(---cy) - var(--dy)))
                            translateZ(calc(var(---cz) - var(--dz)))
                            translate(-50%, -50%)
                            var(---r)
                            ;
                    }
                    &amp;:nth-of-type(2) {
                        color: green;
                        transform: 
                            var(--r)
                            translateX(calc(var(---cx) - var(--dx)))
                            translateY(calc(var(---dy) - var(--dy)))
                            translateZ(calc(var(---cz) - var(--dz)))
                            translate(-50%, -50%)
                            var(---r) 
                            ;
                        position: absolute;
                    }
                    &amp;:nth-of-type(3) {
                        color: blue;
                        transform: 
                            var(--r)
                            translateX(calc(var(---cx) - var(--dx)))
                            translateY(calc(var(---cy) - var(--dy)))
                            translateZ(calc(var(---dz) - var(--dz)))
                            translate(-50%, -50%)
                            var(---r) 
                            ;
                        position: absolute;
                        &amp; ~ th {
                            display: none;
                        }
                    }
                }
                td, th {
                    display: block;
                }
                td{
                    border: 1px solid var(--fg);
                    background: var(--bg);
                }
            }
        }
    }
}
```
    FLAT =\
```text/css


```
    XY =\
```text/css    
table.ddd {
}
```

    YZ =\
```text/css
table.ddd {
    --r: rotateY(270deg);
    ---r: rotateY(-270deg);
}
```

    XZ =\
```text/css    
table.ddd {
    --r: rotateX(270deg);
    ---r: rotateX(-270deg);
}
```

the self contained event to fire when the `section.form.fieldset` is updated.

    update_view =\
```text/javascript
if (this.checked) {
    document.getElementById(`www`).classList.toggle(`ddd`, this.getAttribute(`aria-controls`) != `www`);
}
document.querySelectorAll(`[name=view][aria-controls]`).forEach((thing)=&gt;{    
    var target = document.getElementById(thing.getAttribute(`aria-controls`));
    if (target.tagName == `STYLE`) {
        target.setAttribute("media", thing.checked ? "all" : "none");
    } 
});
```
section = g.pipe(get_table, id="www", caption="random ass 3d data")
section.style.string = "\n".join((PROPERTIES, DDD, section.style.string))
section.attrs.update(id="demo")

for row in section.table.select("tr"):
    row.attrs.update(onclick="""
    this.hasAttribute(`aria-selected`) ? this.removeAttribute(`aria-selected`) : this.setAttribute(`aria-selected`, `true`);
""".strip())
section.table.attrs.update({"class": "ddd"})
section.form.attrs.setdefault("style", "") 
section.form.attrs["style"] += "display: block;"
section.form.extend((
    new("fieldset", new(
        "legend", "Prepared views", 
        new("ul", 
            new("li", new("label", 
                 new("input", type="radio", name="view",  **aria(controls="www"), onchange=update_view),
                "default table view"
            ), 
            new("li", 
                 new("input", type="radio", name="view", **aria(controls="xy"), checked="", onchange=update_view), "x-y scatter view"
            ), 
            new("li", 
                 new("input", type="radio", name="view", **aria(controls="yz"), onchange=update_view), "y-z scatter view"
            ), new("li", 
                 new("input", type="radio", name="view", **aria(controls="xz"), onchange=update_view), "x-z scatter view"
            ), role="group")
    ))

), 
    new("style", FLAT, id="flat",  media="none"), new("style", XY, id="xy",  media="all"),
    new("style", YZ, id="yz", media="none"), new("style", XZ, id="xz", media="none"),
))
section
random ass 3d data
pandas dataframe with 30 rows, 4 columns with 5 index levels and 1 columns levels.
X Y Z A position 'x' 'y' 'z' 'a'
-2.100 -0.700 -2.400 1.100 25.000 -2.127 -0.704 -2.402 1.122
-1.900 -2.100 1.100 0.400 12.000 -1.943 -2.113 1.076 0.432
-1.200 -1.200 1.000 0.000 22.000 -1.221 -1.228 0.991 -0.008
-1.000 -0.800 -1.000 2.200 11.000 -1.001 -0.765 -0.994 2.194
-0.900 -0.700 -0.400 -0.700 0.000 -0.942 -0.689 -0.355 -0.717
-0.800 -0.200 0.500 -0.100 4.000 -0.771 -0.240 0.512 -0.137
-0.700 -1.000 0.500 0.800 15.000 -0.692 -0.980 0.454 0.846
-0.700 0.300 0.200 -1.100 10.000 -0.654 0.346 0.220 -1.061
-0.700 1.300 -0.000 -1.400 7.000 -0.700 1.302 -0.029 -1.375
-0.500 -0.500 -0.200 -0.100 9.000 -0.541 -0.507 -0.179 -0.127
-0.300 -0.900 2.200 0.300 21.000 -0.284 -0.861 2.156 0.348
-0.300 0.200 0.500 -0.300 17.000 -0.341 0.165 0.541 -0.265
-0.200 -3.300 0.700 -0.300 8.000 -0.217 -3.321 0.654 -0.285
-0.200 -0.700 0.200 1.300 3.000 -0.206 -0.686 0.230 1.347
-0.000 -0.400 -0.000 0.200 18.000 -0.007 -0.449 -0.038 0.165
-0.000 0.000 -1.500 -0.600 1.000 -0.013 0.010 -1.462 -0.569
-0.000 0.000 -0.000 0.000 29.000 0.000 0.000 0.000 0.000
0.100 -2.700 0.200 0.900 16.000 0.118 -2.702 0.182 0.862
0.300 1.800 -0.900 0.600 14.000 0.344 1.773 -0.942 0.599
0.400 1.200 1.000 0.000 2.000 0.360 1.197 1.020 0.027
0.500 -1.600 -0.400 1.100 6.000 0.465 -1.602 -0.361 1.136
0.500 -0.800 -1.000 -0.400 19.000 0.493 -0.840 -1.022 -0.408
0.500 -0.800 -0.400 0.000 27.000 0.492 -0.770 -0.412 -0.014
0.500 -0.300 -0.700 -1.100 5.000 0.543 -0.280 -0.684 -1.072
0.600 0.800 0.600 -0.200 26.000 0.578 0.780 0.561 -0.226
0.800 -0.200 -0.600 -0.700 20.000 0.830 -0.173 -0.558 -0.724
1.000 1.400 0.200 -0.200 13.000 1.028 1.411 0.243 -0.163
1.100 -0.500 -0.300 -0.400 24.000 1.108 -0.529 -0.306 -0.391
1.300 -1.500 3.100 -0.100 23.000 1.306 -1.534 3.132 -0.089
1.400 0.400 0.600 -0.100 28.000 1.441 0.441 0.644 -0.106
min -2.127 -3.321 -2.402 -1.375
max 1.441 1.773 3.132 2.194
diff 3.568 5.094 5.533 3.569
Prepared views
  • x-y scatter view
  • y-z scatter view
  • x-z scatter view
%%html                                    
<style>
a[href="#demo"] {
    display: block;
    height: 300px;
    width: 400px;
    background: -moz-element(#demo);
    background-size: content;
    background-repeat: no-repeat;
    font-size: 4rem;
}
</style>