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;
&: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;
&: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)
;
}
&: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;
}
&: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;
& ~ 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)=>{
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
|
%%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>