rendering dataframes for screen readers with pandas
description
in the document we'll explore what it takes to make pandas.DataFrames accessible.
we'll follow Paul J Adam's instructions for making Simple Data Tables.
# rendering dataframes for screen readers with `pandas`
in the document we'll explore what it takes to make `pandas.DataFrame`s accessible.
we'll follow [Paul J Adam's](https://pauljadam.com) instructions for making [Simple Data Tables](https://pauljadam.com/demos/data-tables.html#heading1).
in the document we'll explore what it takes to make
pandas.DataFrame
s accessible.
we'll follow
Paul J Adam's
instructions for making
Simple Data Tables
.
(df:=pandas.DataFrame(columns=pandas.Index(list("ABC")),index=pandas.Index(range(2),name="index"))).style.set_caption("the basic dataframe <var>df</var> we use for explanation in this document. ")
### 1. Title of data table is inside the `<caption>` element.thecaptionisdependentonthedataandeffectsthevisualappearanceofthetable.itiscontextdependentuptotheauthortosupply.
defassert_has_caption(object):caption=soup(object).select_one("table caption")assertcaptionandcaption.string.strip(),"table is missing a <caption>"# with pytest.raises(AssertionError): assert_has_caption(df._repr_html_())
the caption can be set using the `pandas.DataFrame.style.set_caption` method.
the result is a `pandas.io.formats.style.Styler` object that let's us modify how the
instance is displayed.
3
the caption can be set using the
pandas.DataFrame.style.set_caption
method.
the result is a
pandas.io.formats.style.Styler
object that let's us modify how the
instance is displayed.
the`<table>`belowdemonstrateshowthe`<caption>`appearsona`captioned``pandas.DataFrame`.{{captioned}}assert_has_caption(captioned:=set_caption(df,"a value-less dataframe with columns and row indexes")._repr_html_());
defassert_has_col_scope(object,selector="thead tr th"):forbasicframes,allthe`<th>`tagsin`<thead>`shouldhave`scope="col"`assertall(th.attrs.get("scope")in{"col","colgroup"}forthinsoup(object).select(selector)),"<th> is missing `scope='col'`"# with pytest.raises(AssertionError): assert_has_col_scope(captioned)
defassert_has_row_scope(object,selector="tbody tr th"):assertall(th.attrs.get("scope")in{"row","rowgroup"}forthinsoup(object).select(selector)),\
"<th> is missing `scope='col'`"# with pytest.raises(AssertionError): assert_has_row_scope(col_scoped)
weuse`set_row_scope`toverifythe`scope`because,again,therearen't any visual effects to these changes.assert_has_row_scope(row_scoped:=set_row_scope(col_scoped))
### 5. Header cells with text abbreviations that need expansion use the title attribute with the expanded text set as the value.thenamingofcolumnsisacontextspecificscreenreaderfeature.authorswouldhavetoaddthisinformationthemselves.
## inconsistencies in labelled indexeseverythinggoestohellwith`named_column`whichasacolumnname.named_column=df.copy()named_column.columns.name="letters"
### column and index namesconsiderthecaseof`df2`wherethe`df2.columns`isnamedand`df2.index`isnot.{%setdf=named_column.style.set_caption(pidgy.filters.md("the `named_column` dataframe with a column name"))%}{{df}}screenreadervisitorsmaystruggletointerpretthemeaningof"letters"relativetotheindex.ensurelyaproperexperienceforscreenreaderswillrequireextramarkuptogroupthe`<th>withthecolumns.
### column name and no index namenamed_column_no_index=named_column.copy()named_column_no_index.index.name=None{%setdf=named_column_no_index.style.set_caption(pidgy.filters.md("the `named_column_no_index` dataframe with a column name and without an index name"))%}{{df}}inthisconformation,itispossibleforascreenreadertomisinterpet`letters`asthenameoftheindexcolumn.whenthecolumnindexisnamed,like`letters`,theentryshouldbe`<thscope="row">`.itthisexamplewecanseehowinstructionsin2and3differ.
### final frameourfinaldataframehas:-[x]`<caption>`-[x]`<thscope="col">`-[x]`<thscope="row">`-[x]noempty`<th>`-[x]`<thtitle>`forabbreviations{{final}}### final html source```html{{final}}```
### about the `scope` attribute<qcite="https://www.w3schools.com/tags/att_scope.asp">Thescopeattributespecifieswhetheraheadercellisaheaderforacolumn,row,orgroupofcolumnsorrows.</q><qcite="https://dequeuniversity.com/rules/axe/4.0/scope-attr-valid">Thescopeattributemakestablenavigationmucheasierforscreenreaderusers,providedthatitisusedcorrectly.Incorrectlyused,scopecanmaketablenavigationmuchharderandlessefficient.<q>