skip to main content

@tonyfast s notebooks

site navigation
notebook summary
title
3d plots from html tables
description
lets use html and html to try to make a 3d plot. most plotting is an ends where the table is the means. if we can generate plots from tabular data then we could encourage more complete tables in scientific literature.
cells
8 total
7 code
state
executed in order
kernel
Python [conda env:p311] *
language
python
name
conda-env-p311-py
lines of code
165
outputs
5
table of contents
{"kernelspec": {"display_name": "Python [conda env:p311] *", "language": "python", "name": "conda-env-p311-py"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.3"}, "widgets": {"application/vnd.jupyter.widget-state+json": {"state": {}, "version_major": 2, "version_minor": 0}}, "title": "3d plots from html tables", "description": "lets use html and html to try to make a 3d plot. most plotting is an ends where the table is the means.\nif we can generate plots from tabular data then we could encourage more complete tables in scientific literature."}
notebook toolbar
Activate
cell ordering
1

3d plots from html tables

lets use html and html to try to make a 3d plot. most plotting is an ends where the table is the means. if we can generate plots from tabular data then we could encourage more complete tables in scientific literature.

2
3 1 outputs.

making sample data

create some randomized datasets with distinct clusters

import sklearn.datasets, sklearn.discriminant_analysis, sklearn.model_selection
features = 6
df = pandas.DataFrame(*sklearn.datasets.make_blobs(200, features, centers=[
    (i**2,)*features for i in range(features)
]))

df = pandas.concat(dict(zip("test train".split(), sklearn.model_selection.train_test_split(df))))
df = df.rename_axis(index="selection blob".split())

apply statistical analysis to reduce the dimensionality of the data. a sample of the full and reduced dataset are shown next, with the source as a caption.

    0 1 2 3 4 5 x y z
test 3 9.830273 9.151163 11.189289 9.057340 8.674574 8.675005 1.104807 -0.331329 -0.317266
1 0.111571 1.710573 0.153907 2.878302 1.887411 0.045487 -22.539861 -1.035561 -1.366237
model = sklearn.discriminant_analysis.LinearDiscriminantAnalysis(n_components=3)
model.fit(df.loc["test"], df.loc["test"].index)
df = df.combine_first(
    pandas.DataFrame(model.transform(df.values), columns=list("xyz"), index=df.index)
)
df = pandas.concat([df, pandas.DataFrame([[-1]*features+ [0,0,0]] , pandas.MultiIndex.from_tuples([("test", -1)]), df.columns)])
4 2 outputs.

generate a 3d plot in an image for comparsion

we'll compare our interactive css outcomes with rendered html image.

import matplotlib.pyplot
fig = matplotlib.pyplot.figure()
ax = fig.add_subplot(projection="3d")
df[list("xyz")].apply(lambda x: ax.scatter(*x.values, c=x.name[1]), axis=1);
No description has been provided for this image
5 1 outputs.

creating our table

table =\
0 4.64 2.66 4.03 3.56 2.23 3.19
1 -0.40 0.90 -0.06 0.89 -0.69 -0.38
2 -0.45 0.18 -2.10 -0.38 0.54 -1.37
3 16.21 17.33 15.45 17.27 15.97 15.45
4 7.53 10.52 9.06 9.56 8.66 8.73
5 0.28 -0.05 -0.24 0.08 0.02 0.21
6 15.94 15.45 16.67 14.37 16.28 15.61
7 0.12 1.74 0.10 0.60 0.15 0.76
8 15.75 17.21 14.96 15.63 14.07 17.78
9 8.71 10.97 7.89 9.41 9.32 9.49
10 24.13 25.24 25.34 24.84 23.15 26.47
11 8.44 8.27 8.16 9.03 9.61 9.10
12 14.33 15.71 16.98 13.71 15.52 16.83
13 23.60 25.49 23.69 25.85 24.52 24.45
14 15.47 17.22 15.56 17.01 13.34 15.80
15 0.87 -1.34 1.31 2.12 2.56 0.11
16 7.96 7.96 8.95 8.84 7.74 10.23
17 5.34 3.44 5.43 4.03 3.90 5.23
18 25.15 26.99 24.34 24.62 26.16 24.42
19 24.70 24.79 25.84 25.69 24.37 25.85
20 24.64 25.22 26.11 25.70 26.45 26.19
21 15.61 17.28 16.06 16.42 16.74 16.64
22 4.05 5.22 4.00 3.71 4.62 3.99
23 25.23 25.37 26.40 25.19 25.12 25.74
24 0.51 -0.01 1.14 0.69 -0.01 0.72
25 16.56 15.88 16.09 14.97 15.59 14.16
26 3.13 6.06 2.68 4.42 4.78 4.42
27 14.47 17.15 16.48 15.24 18.20 14.89
28 9.23 7.90 9.89 9.14 9.06 7.84
29 1.04 1.52 0.92 1.38 -0.45 1.32
30 -0.01 0.71 1.84 0.11 -1.28 2.03
31 5.51 4.33 2.77 3.52 3.71 4.89
32 2.66 3.72 3.27 2.51 3.49 4.31
33 -0.44 0.64 -1.21 -0.63 -1.24 -1.23
34 25.33 25.12 24.48 27.23 24.43 25.07
35 17.75 16.14 16.25 16.42 15.75 16.28
36 1.22 0.13 1.96 2.61 0.64 1.91
37 24.33 23.87 27.23 26.23 24.95 23.57
38 16.05 15.68 16.65 16.29 16.08 17.54
39 16.80 16.38 14.03 15.69 17.15 16.62
40 9.83 9.15 11.19 9.06 8.67 8.68
41 17.17 15.00 15.90 16.09 16.78 17.17
42 25.40 26.41 24.46 24.82 23.61 25.79
43 9.38 7.95 9.86 9.12 8.37 10.35
44 8.75 9.01 8.24 9.41 8.90 9.90
45 8.85 6.07 9.58 9.93 8.18 10.17
46 26.11 25.75 24.47 25.43 24.61 24.04
47 1.29 1.34 0.05 1.20 2.71 0.82
48 16.29 16.59 14.49 15.50 15.61 17.31
49 0.91 -0.13 0.88 1.74 1.38 2.78
50 4.17 5.43 5.04 5.19 2.73 3.78
51 8.07 7.23 10.81 11.19 7.92 7.74
52 0.44 -1.06 0.68 1.54 0.60 -0.03
53 16.49 16.69 15.62 15.77 16.34 16.91
54 -2.27 -0.38 0.70 -1.48 0.73 0.13
55 8.88 9.93 9.06 8.25 8.82 9.37
56 9.33 9.03 8.89 8.47 9.76 10.15
57 9.16 8.43 6.90 9.56 8.58 10.57
58 9.63 9.91 9.81 11.21 8.73 8.13
59 15.18 15.80 16.27 16.52 16.97 16.95
60 7.62 7.91 11.73 9.24 9.61 9.03
61 2.17 1.35 -0.18 1.53 0.67 0.01
62 16.84 17.37 16.91 13.59 17.12 16.28
63 -0.76 2.35 0.33 0.73 0.03 -0.07
64 24.91 23.63 24.15 22.53 24.40 26.12
65 23.85 24.56 24.75 25.10 24.82 24.84
66 8.12 8.73 9.86 6.23 8.04 10.16
67 24.40 26.12 23.99 22.18 25.70 24.59
68 3.65 4.47 3.69 2.61 4.07 3.62
69 10.58 9.95 9.18 8.91 9.38 8.14
70 2.40 -0.06 1.04 1.24 -0.09 0.26
71 4.63 2.83 3.83 3.99 4.13 4.08
72 16.31 16.59 16.29 16.85 16.04 15.22
73 5.01 4.42 4.38 5.24 4.27 4.43
74 0.11 1.71 0.15 2.88 1.89 0.05
75 3.23 2.47 3.94 2.87 5.69 5.06
76 5.21 5.50 4.26 3.65 3.75 4.08
77 -0.21 -1.87 -0.35 -0.07 0.54 -0.62
78 9.18 8.96 9.95 9.61 10.17 7.38
79 23.48 24.82 26.37 24.89 24.70 26.22
80 1.18 -1.39 -0.02 -0.30 1.41 1.22
81 15.63 16.10 15.95 16.80 15.42 16.64
82 -0.90 -0.30 -0.83 -2.16 0.08 -0.00
83 9.76 9.95 8.63 10.35 9.62 8.27
84 25.74 25.30 24.26 22.64 25.92 26.94
85 -1.53 -0.21 0.26 -1.46 -0.04 -0.82
86 14.95 17.04 17.22 15.75 16.67 17.09
87 25.00 24.29 26.78 24.79 25.44 27.19
88 2.03 1.11 0.26 1.65 1.95 0.27
89 -0.61 0.25 -0.14 -0.07 0.36 -0.64
90 3.68 4.72 4.13 2.85 4.84 4.22
91 -1.31 1.46 0.40 0.76 0.21 -1.59
92 -0.39 4.18 2.55 0.47 0.41 0.22
93 24.86 26.24 25.37 23.57 25.37 24.52
94 -0.65 0.36 0.20 1.17 -0.21 -0.68
95 -0.48 2.06 3.72 2.38 1.30 2.39
96 24.53 25.99 22.95 25.38 24.43 24.60
97 4.22 4.27 5.29 4.59 3.96 5.94
98 0.07 0.41 -0.26 0.44 4.84 1.35
99 0.30 1.09 -0.81 1.09 1.22 -1.04
100 5.11 4.89 3.67 4.33 2.30 4.70
101 0.17 0.34 1.61 -0.40 -1.74 -1.17
102 2.19 1.17 -1.00 1.09 2.11 -0.46
103 -0.28 0.78 0.92 -0.86 -1.12 -0.39
104 3.23 0.98 -0.92 2.24 1.56 2.54
105 15.81 17.77 16.60 15.46 16.18 16.04
106 24.40 23.84 24.42 23.64 25.38 25.11
107 25.17 23.06 25.93 23.83 25.05 26.29
108 -1.26 -0.25 -1.30 1.26 0.45 -0.02
109 4.07 4.91 3.49 3.35 4.91 5.43
110 8.39 10.89 9.09 11.57 10.16 9.41
111 1.80 0.07 1.57 0.73 1.43 1.31
112 -0.20 0.31 0.24 0.85 -0.73 0.53
113 0.90 0.20 1.11 1.07 1.99 0.14
114 24.37 26.31 24.17 25.64 26.33 24.51
115 -0.87 1.73 -0.38 1.07 0.48 0.17
116 4.08 3.51 3.31 4.53 3.71 5.39
117 -1.77 0.49 -1.46 0.61 1.24 0.06
118 -0.96 -0.61 -0.38 -1.47 -1.31 0.65
119 0.79 -0.70 -0.71 -0.09 1.01 -0.52
120 16.52 16.57 15.64 15.62 16.36 15.94
121 5.44 4.63 4.01 4.51 4.62 2.83
122 16.53 16.93 17.15 16.63 14.74 16.13
123 -0.09 0.20 1.02 -1.72 -0.57 0.25
124 16.89 16.50 16.24 16.96 14.35 16.78
125 1.53 0.42 -0.59 0.85 1.39 2.42
126 7.96 8.55 8.43 9.97 8.58 8.97
127 10.03 7.91 11.14 7.36 7.79 8.58
128 14.59 17.72 16.23 15.97 15.86 15.95
129 7.30 9.90 8.18 10.04 9.06 7.72
130 11.29 8.72 7.87 9.27 10.21 7.29
131 2.75 3.83 3.96 2.72 5.24 4.08
132 -1.82 -1.45 1.32 -0.52 0.38 -0.49
133 3.60 3.42 6.28 3.98 3.76 4.20
134 4.04 2.86 3.96 3.82 4.37 2.35
135 7.79 9.05 10.64 8.38 7.96 10.99
136 10.44 10.27 9.40 7.95 7.84 9.29
137 8.85 8.68 8.74 9.81 9.17 9.30
138 3.33 3.65 3.41 2.46 4.33 5.27
139 3.17 3.69 3.94 4.90 3.64 4.44
140 25.78 24.62 22.82 26.84 24.70 24.24
141 3.51 3.74 4.89 3.23 3.77 4.41
142 0.69 -1.29 0.23 1.02 -1.82 -1.24
143 1.54 0.70 0.29 -0.69 0.55 1.85
144 -0.11 0.93 -0.79 0.81 -0.04 -0.29
145 25.96 25.13 25.87 24.48 23.63 24.93
146 0.74 1.57 0.94 0.91 0.65 0.12
147 16.26 14.83 16.97 13.46 17.16 15.29
148 4.85 5.78 2.66 5.95 3.62 4.29
149 26.34 24.75 23.10 24.26 25.51 26.16
150 4.78 3.55 2.82 2.99 4.02 3.56
151 24.31 26.13 25.67 24.47 23.95 25.87
152 27.23 24.66 25.13 25.14 24.40 24.49
153 2.97 5.74 4.87 4.47 3.67 4.25
154 14.07 18.04 15.54 15.78 16.60 15.29
155 2.74 4.53 3.67 5.55 6.33 3.48
156 2.73 2.23 -0.83 0.75 0.95 0.92
157 3.32 5.55 4.90 4.76 3.75 5.32
158 8.52 9.95 9.54 7.13 8.23 8.29
159 1.97 0.44 0.93 -0.57 -0.18 1.71
160 9.27 8.34 10.21 9.19 8.60 7.39
161 -0.56 0.39 1.26 -0.66 -1.86 0.03
162 25.10 25.65 25.57 26.44 24.64 25.87
163 0.88 0.21 4.41 -0.45 1.32 1.54
164 22.40 25.83 25.11 23.84 24.36 25.74
165 -0.12 0.54 -0.60 1.09 -1.44 0.54
166 0.05 -0.16 -0.18 -1.32 -0.01 -1.08
167 -0.68 3.14 -1.02 0.77 1.04 -0.23
168 8.63 9.90 10.43 7.89 8.78 8.95
169 3.41 2.09 6.91 4.79 4.46 2.87
170 -0.42 0.93 0.79 -0.73 -0.08 0.55
171 3.72 2.99 4.84 4.70 4.31 2.13
172 24.95 24.47 26.43 25.52 26.00 24.94
173 15.92 15.79 13.99 14.69 17.84 15.78
174 16.76 16.36 14.80 15.70 15.11 14.68
175 3.03 0.01 0.30 0.41 1.77 1.17
176 8.18 9.33 9.66 8.89 8.78 7.48
177 4.23 6.10 3.82 4.51 5.30 2.99
178 7.76 8.79 10.10 8.35 8.29 8.56
179 16.06 16.32 15.56 16.23 15.14 16.03
180 -0.61 2.33 2.53 0.16 -0.55 2.65
181 -0.55 0.42 1.19 -0.26 -0.59 -1.92
182 0.94 1.04 2.52 2.34 0.37 2.03
183 1.12 0.29 2.40 1.22 1.36 0.19
184 16.65 16.43 16.35 16.62 16.62 18.20
185 24.24 24.02 25.35 25.11 23.10 25.53
186 7.70 7.86 11.13 9.69 9.08 9.59
187 15.52 15.69 15.81 16.38 15.32 15.71
188 25.34 23.46 26.41 25.23 24.53 24.83
189 0.30 -0.50 0.74 0.31 -1.13 0.67
190 2.09 0.49 0.97 0.75 0.11 1.15
191 16.31 16.55 16.73 17.47 15.42 17.27
192 2.49 3.08 1.54 0.16 0.37 1.87
193 25.95 24.45 24.63 25.04 23.77 25.21
194 0.29 -0.83 0.58 -1.33 0.20 0.76
195 24.61 23.81 25.81 26.55 26.70 26.65
196 14.09 16.30 17.44 17.19 18.35 15.33
197 0.74 1.92 1.04 2.29 1.95 -0.02
198 3.54 3.54 3.87 3.47 3.95 5.37
199 1.35 0.99 0.35 1.21 1.14 1.28
200 -1.00 -1.00 -1.00 -1.00 -1.00 -1.00
form =\
html table source
{% set format="%.2f" %}
<table role=table id=pca>
    <tbody role=rowgroup style="--x-min: {{df.x.min()}}; --x-max: {{df.x.max()}}; --y-min: {{df.y.min()}}; --y-max: {{df.y.max()}}; 
    --z-min: {{df.z.min()}}; --z-max: {{df.z.max()}};">
    {%- for i, (_, row) in enumerate(df.iterrows()) -%}
        <tr role=row style="--x: {{row.loc['x']}}; --y: {{row.loc['y']}}; --z: {{row.loc['z']}};">
        <th role=rowheader>{{i}}</th>
        {%- for j in range(features) -%}
        <td role=cell>{{format % row.loc[j]}}</td>
        {%- endfor %}{% for j in "xyz" -%}
        <td role=cell hidden>{{ row.loc[j]}}</td>
        {%- endfor %}</tr>
    {%- endfor %}</tbody>
</table>
form source
<form name=controls>
    <script>
    function rotate(axis, el){
        document.getElementById("pca").style.setProperty(`--rotate-${axis}`, `${el.value}deg`);
    }
    </script>
    <label>x
    <input type=range min=0 max=360 value=350 step=5 oninput="rotate('x', this)" name="x"/>
    </label>
    <label>y
    <input type=range min=0 max=360 value=5 step=5 oninput="rotate('y', this)" name="y"/>
    </label>
    <label>z
    <input type=range min=0 max=360 value=15 step=5 oninput="rotate('z', this)" name="z"/>
    </label>
    <label>show table<input type=checkbox name=show checked onchange="document.getElementById('pca-style').setAttribute('media', this.checked ? 'screen': 'none')"/></label>
</form>

<details>
<summary>html table source</summary>
6 1 outputs.

styling the table

style the table using 3d css transform, rotations, and translations.

style =\
...
css with 3d translations, transformations, and rotations
<style id=pca-style media=screen>
.jp-RenderedHTMLCommon tbody tr:hover {
    background: unset;
}
#pca {
    --height: 600px;
    --width: 600px;
    --depth: 600px;
    --rotate-x: 0deg;
    --rotate-y: 0deg;
    --rotate-z: 0deg;
    display: block;
    position: relative;
    width: var(--width);
    height: var(--height);
    margin-left: auto;
    margin-right: auto;
    tbody{
        perspective: .3;
        border: solid;
        position: absolute;
        display: block;
        top: 0;
        left: 0;
        width: var(--width);
        height: var(--height);
        --dx: calc(var(--x-max) - var(--x-min));
        --dy: calc(var(--y-max) - var(--y-min));
        --dz: calc(var(--z-max) - var(--z-min));
        --x-origin: calc(-1 * var(--x-min) / var(--dx) * var(--width));
        --y-origin: calc(var(--y-max) / var(--dy) * var(--height));
        transform-style: preserve-3d;
    }
    tr {        
        top: 0;
        left: 0;
        position: absolute;
        display: inline-block;
        transform-origin: var(--x-origin) var(--y-origin) 0;
        transform: 
            translateX(var(--x-origin)) translateY(var(--y-origin))
            rotateZ(calc(360deg - var(--rotate-z))) 
            rotateY(calc(360deg - var(--rotate-y)))  
            rotateX(calc(360deg - var(--rotate-x)))
            translateX(calc(var(--x) / var(--dx) * var(--width)))
            translateY(calc(-1 * var(--y) / var(--dy) * var(--height)))
            translateZ(calc(var(--z) / var(--dz) * var(--depth)))
            rotateX(var(--rotate-x)) rotateY(var(--rotate-y)) rotateZ(var(--rotate-z));
        td {
            display: none;
        }
    }
    tr:hover, tr:focus-within {
         transform: 
            translateX(var(--x-origin)) translateY(var(--y-origin))
            rotateZ(calc(360deg - var(--rotate-z))) 
            rotateY(calc(360deg - var(--rotate-y)))  
            rotateX(calc(360deg - var(--rotate-x)))
            translateX(calc(var(--x) / var(--dx) * var(--width)))
            translateY(calc(-1 * var(--y) / var(--dy) * var(--height)))
            translateZ(calc(var(--z) / var(--dz) * var(--depth)))
            rotateX(var(--rotate-x)) rotateY(var(--rotate-y)) rotateZ(var(--rotate-z))
            translateZ(10000px);
        th, td:not([hidden]) {
            display: unset;
        }
    }
    tr:last-of-type {
        background-color: red;
    }
}
</style>
...;
7

8