Skip to content

histograms suck¤

what is an accessible histogram made out of a table? in this form AT have access to each entry and tactile navigation.

i use synthetic data which kinda makes a crumby demo, but the idea could be sound independent of data.

    %%capture
    import pandas, random, midgy, string
    import importnb
    with __import__("importnb").Notebook(): from __multi__aria import get_table

synthetic data that creates a histogram like looking dataframe

    data = pandas.RangeIndex(100).to_series().apply(lambda x: random.random()*10).astype(int).value_counts()
    hist = data.to_frame().reindex(pandas.RangeIndex(min(data.index), max(data.index)))
    hist = hist.set_index(hist.index.map(string.ascii_uppercase.__getitem__))
    hist = hist.rename_axis("category", axis=0)
    hist.T.pipe(get_table)
rows
1
columns
9
indexes:
rows
1
columns
1
categoryABCDEFGHI
count9915511710710

customize the style with pandas styler. do some weird shit so we have access to a string and numerical version of the value. content can't show a string and we can't math on a string so we need both. this is redundant, but lets stick to css.

hist.T.map(
    lambda x: F"""<data style="--val: {x}">{x}</data>"""
).style.set_table_attributes("""class="hist v" """).set_caption("a vertical histogram of sythetic data to demostrate the technique.")
a vertical histogram of sythetic data to demostrate the technique.
category A B C D E F G H I
count 9 9 15 5 11 7 10 7 10

now some css to make it visually appear like histogram

%%
    display\
```html
<style>
table caption dl[role=presentation] {
    display: inline-flex !important;
    justify-content: flex-start;
}
table.hist {
    table-layout: fixed;
    &, td, th {border: none !important;}
    th, td {
        position: relative;
        data {
            position: relative;
            display: inline-block;
            background-color: darkslategray;
            color: white;
        }
    }
}
table.hist {
    &.v {
        width: 100%;
    }
    &.v :is(th,td) {
        top: 0;
        vertical-align: bottom;   
        text-align: center !important;

    }
    &.v data {
        vertical-align: bottom;
        text-align: center;
        width: 100%;
        height: calc(var(--val)*1rem);
    }
    &.h data {
        float: left;rt
        vertical-align: bottom;
        text-align: left;
        left: 0;
        width: calc(var(--val)*1rem);

    }
}
</style>
```
display\

html <style> table caption dl[role=presentation] { display: inline-flex !important; justify-content: flex-start; } table.hist { table-layout: fixed; &, td, th {border: none !important;} th, td { position: relative; data { position: relative; display: inline-block; background-color: darkslategray; color: white; } } } table.hist { &.v { width: 100%; } &.v :is(th,td) { top: 0; vertical-align: bottom; text-align: center !important; } &.v data { vertical-align: bottom; text-align: center; width: 100%; height: calc(var(--val)*1rem); } &.h data { float: left;rt vertical-align: bottom; text-align: left; left: 0; width: calc(var(--val)*1rem); } } </style>

hist.map(
    lambda x: F"""<data style="--val: {x}">{x}</data>"""
).style.set_table_attributes("""class="hist h" """).set_caption("a horizontal histogram of sythetic data to demostrate the technique.")
a horizontal histogram of sythetic data to demostrate the technique.
  count
category  
A 9
B 9
C 15
D 5
E 11
F 7
G 10
H 7
I 10
hist.map(
    lambda x: F"""<data style="--val: {x}">{x}</data>"""
).style.set_table_attributes("""class="hist h" """).set_caption("a histogram of sythetic data to demostrate the technique.")
a histogram of sythetic data to demostrate the technique.
  count
category  
A 9
B 9
C 15
D 5
E 11
F 7
G 10
H 7
I 10
hist.sort_values(by="count", ascending=False).map(
    lambda x: F"""<data style="--val: {x}">{x}</data>"""
).style.set_table_attributes("""class="hist h" """).set_caption("a sorted vertical histogram of sythetic data to demostrate the technique.")
a sorted vertical histogram of sythetic data to demostrate the technique.
  count
category  
C 15
E 11
I 10
G 10
A 9
B 9
F 7
H 7
D 5
hist.sort_values(by="count", ascending=False).T.map(
    lambda x: F"""<data style="--val: {x}">{x}</data>"""
).style.set_table_attributes("""class="hist v" """).set_caption("a sorted vertical histogram of sythetic data to demostrate the technique.")
a sorted vertical histogram of sythetic data to demostrate the technique.
category C E I G A B F H D
count 15 11 10 10 9 9 7 7 5