# ansitable: Quick and easy display of tabular data and matrices with optional ANSI color and borders Documentation: https://petercorke.github.io/ansitable/ ansitable prints tabular data and NumPy matrices in a terminal with optional Unicode borders and ANSI color, and exports the same table to Markdown, HTML, LaTeX, reStructuredText, wikitable, CSV and Pandas. It is a small, pure-Python package (one module, `ansitable.table`) whose only dependency is the `colored` package, which provides the color names. It requires Python 3.9 or later. Install with `pip install ansitable`. ## Quick start ```python from ansitable import ANSITable, Column table = ANSITable( Column("Name", headalign="<", colalign="<"), # left-aligned Column("Score", fmt="{:.1f}", colcolor="blue"), border="thin", ) table.row("Alice", 95) table.row("Bob", 87.25) table.row("Carol", 92, fgcolor="red") # color override for one row table.sort("Score", key=float, reverse=True) # in place; returns the table table.print() # to a terminal, or table.print(file=f) ``` ## Key points - **Creating a table.** `ANSITable("a", "b", "c")` makes columns from strings (right-aligned, formatted with `"{}"`). Pass `Column(name, fmt=..., width=..., colcolor=..., colalign=..., headstyle=...)` objects instead for formatting and styling, or call `table.addcolumn(name, **kwargs)`. An alignment marker at the start of a column name, such as `"{<}Name"`, `"{^}Name"`, sets alignment in the string form. - **Adding data.** `table.row(v1, v2, ...)` takes exactly one value per column and formats each with its column's `fmt` (a format string or a callable). `table.rule()` inserts a horizontal rule. `row()` accepts `fgcolor`, `bgcolor` and `style` overrides for the whole row; wrap a value in `Cell(text, fgcolor=..., bgcolor=..., style=...)` to override a single cell, or prefix a string value with `"<>"` for an inline color. - **Borders.** `border=` is one of `"ascii"`, `"thin"`, `"round"`, `"thick"`, `"double"`; the default is no border. `bordercolor=` colors it. - **Colors and styles.** Colors are any of the 256 names accepted by the `colored` package (e.g. `"red"`, `"dodger_blue_1"`) or a `"#rrggbb"` hex string. Styles are `"bold"`, `"dim"`, `"underlined"`, `"blink"`, `"reverse"`. Colors and styles are validated when the `Column`, `Cell` or row is created, and raise `ValueError` there, not later at print time. - **Output.** `table.print()` writes to stdout (or `file=`); `str(table)` gives the rendered text. Export methods return strings: `.markdown()`, `.rest()`, `.wikitable()`, `.html()`, `.latex()`, `.csv()`, and `.pandas()` which returns a DataFrame. `table.export(format, file=None, **kwargs)` is a single entry point to them: it returns the string, or writes to a path or open stream, and infers `format` from the file extension if omitted. Missing values (`None`) are shown as `na_rep` (default blank, set on the table or per `Column`) and `fmt` is not applied to them. `width=` on a `Column` truncates over-wide cells (with an ellipsis unless `ellipsis=False`); columns without a width never truncate. `ANSITable.Pandas(df, **kwargs)` goes the other way. - **Global switches.** `ansitable.options(use_unicode, color=None)` turns Unicode box-drawing and ANSI color off (or on) for all tables; with Unicode off, borders fall back to `"ascii"`. Use it when output goes to a log file or a terminal that can't render them. Each table also has its own `color=` argument. If `colored` is not installed, color is silently disabled. - **Sorting.** `table.sort(column, key=None, reverse=False)` sorts rows in place by column name or zero-based index. The default key compares the *formatted strings*, so pass `key=float` (or similar) to sort numerically. Rules inserted with `rule()` are dropped by a sort. - **Matrices.** `ANSIMatrix(style="thin", fmt="{:< 10.3g}", squish=100)` is a formatter for NumPy arrays: `ANSIMatrix().print(m)` or `.str(m)` draws the array inside brackets. Elements smaller than `squish` times machine epsilon are shown as zero. ## Common mistakes - `row()` must be given exactly as many values as there are columns, otherwise it raises `ValueError`. - A `fmt` string is applied with `fmt.format(value)`, so it must suit the value's type (`"{:.1f}"` on a string fails). - The text style and alignment arguments are strings (`"bold"`, `"<"`), not constants or enums. - `ANSIMatrix` needs NumPy; `.pandas()` and `ANSITable.Pandas()` need Pandas. Neither is a dependency of the package. ======================================================================== Page: https://petercorke.github.io/ansitable/index.html ======================================================================== Pretty tables and matrices for Python ************************************* This Python package allows pretty printing of tables and matrices. Tables can also be exported in a number of common markup languages. * Getting Started * Tables * Matrices * Pandas integration * Table classes * Creating a table * Adding a row * Display a table * Sorting tables * Render in markup formats * Matrix class * "ANSIMatrix" * Color reference ======================================================================== Page: https://petercorke.github.io/ansitable/intro.html ======================================================================== Getting Started *************** Tables ====== Painless creation of nice-looking tables of data for Python. Starting simple --------------- from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → Name Age Admission score # → Alice 25 95.1 # → Bob 30 87.3 # → Carol 28 92.1 # → Michelangelo 35 88.0 Note: The lines prefixed by "# →" indicate the **output** of the preceding code block. They are commented to distinguish them from lines of executable code. This also means that if you copy and paste this code, using the icon in the top-right corner of the code block, these output lines will not be executed. The result is a table with column widths automatically chosen, headings and column data all right-justified (default). By default output is written to the console ("stdout"), but you can also: * write to a specific file by passing the "file" option to ".print()" * obtain the table as a multi-line string using "str(table)" Borders ------- You can add borders made up of regular ASCII characters: from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score", border="ascii") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → +--------------+-----+-----------------+ # → | Name | Age | Admission score | # → +--------------+-----+-----------------+ # → | Alice | 25 | 95.1 | # → | Bob | 30 | 87.3 | # → | Carol | 28 | 92.1 | # → | Michelangelo | 35 | 88.0 | # → +--------------+-----+-----------------+ Or use ANSI box-drawing characters (supported by most terminal emulators): from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score", border="thick") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → ┏━━━━━━━━━━━━━━┳━━━━━┳━━━━━━━━━━━━━━━━━┓ # → ┃ Name ┃ Age ┃ Admission score ┃ # → ┣━━━━━━━━━━━━━━╋━━━━━╋━━━━━━━━━━━━━━━━━┫ # → ┃ Alice ┃ 25 ┃ 95.1 ┃ # → ┃ Bob ┃ 30 ┃ 87.3 ┃ # → ┃ Carol ┃ 28 ┃ 92.1 ┃ # → ┃ Michelangelo ┃ 35 ┃ 88.0 ┃ # → ┗━━━━━━━━━━━━━━┻━━━━━┻━━━━━━━━━━━━━━━━━┛ Other border options: ""thin"", ""round"" (thin with rounded corners), and ""double"". Column options -------------- To gain additional control, you can create a table with "Column" objects, which allow you to specify formatting, alignment, and width constraints for each column: from ansitable import ANSITable, Column table = ANSITable( Column("Name", headalign="^", colalign="<"), Column("Age", headalign="^", colalign="<"), Column("Admission score", headalign="^", colalign=">"), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → ┌──────────────┬─────┬─────────────────┐ # → │ Name │ Age │ Admission score │ # → ├──────────────┼─────┼─────────────────┤ # → │ Alice │ 25 │ 95.1 │ # → │ Bob │ 30 │ 87.3 │ # → │ Carol │ 28 │ 92.1 │ # → │ Michelangelo │ 35 │ 88.0 │ # → └──────────────┴─────┴─────────────────┘ Control alignment with "colalign" (data) and "headalign" (heading): * ""<"" - left * "">"" - right (default) * ""^"" - center There is also a shorthand way to control header and column alignment using a format string in the column headers. from ansitable import ANSITable, Column table = ANSITable("{<}Name", "{^<}Age", "{^>}Admission score", border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → ┌──────────────┬─────┬─────────────────┐ # → │ Name │ Age │ Admission score │ # → ├──────────────┼─────┼─────────────────┤ # → │ Alice │ 25 │ 95.1 │ # → │ Bob │ 30 │ 87.3 │ # → │ Carol │ 28 │ 92.1 │ # → │ Michelangelo │ 35 │ 88.0 │ # → └──────────────┴─────┴─────────────────┘ If the header string starts with "{XY}" where "X" and "Y" are alignment characters, these apply to the header and column alignment respectively. If the header string starts with "{X}" then "X" is used as the alignment character for both the header and the column. Width constraints ----------------- Column width can be limited using the "width" argument: from ansitable import ANSITable, Column table = ANSITable( Column("Name", headalign="^", colalign="<", width=10), Column("Age", headalign="^", colalign="<"), Column("Admission score", headalign="^", colalign=">"), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → ┌────────────┬─────┬─────────────────┐ # → │ Name │ Age │ Admission score │ # → ├────────────┼─────┼─────────────────┤ # → │ Alice │ 25 │ 95.1 │ # → │ Bob │ 30 │ 87.3 │ # → │ Carol │ 28 │ 92.1 │ # → │ Michelang… │ 35 │ 88.0 │ # → └────────────┴─────┴─────────────────┘ Text wider than a column's explicit "width" is truncated with an ellipsis (U+2026). Disable with "ellipsis=False" which simply truncates the field. Columns without a "width" are sized to fit their widest cell, so nothing is truncated. Field formatting ---------------- For numeric columns we can specify Python format strings that control how the cell values are rendered. Here we display age in hexadecimal and the score with 2 digits of precision. from ansitable import ANSITable, Column table = ANSITable( Column("Name", headalign="^", colalign="<", width=10), Column("Age", "0x{:x}", headalign="^", colalign="<"), Column("Admission score", "{:.3f}", headalign="^", colalign=">"), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → ┌────────────┬──────┬─────────────────┐ # → │ Name │ Age │ Admission score │ # → ├────────────┼──────┼─────────────────┤ # → │ Alice │ 0x19 │ 95.100 │ # → │ Bob │ 0x1e │ 87.300 │ # → │ Carol │ 0x1c │ 92.100 │ # → │ Michelang… │ 0x23 │ 88.000 │ # → └────────────┴──────┴─────────────────┘ Dividing lines -------------- A dividing line, spanning the entire table, can be added between rows using ".rule()". from ansitable import ANSITable, Column table = ANSITable( Column("Name", headalign="^", colalign="<"), Column("Age", headalign="^", colalign="<"), Column("Admission score", headalign="^", colalign=">"), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.rule() # dividing line table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() # → ┌──────────────┬─────┬─────────────────┐ # → │ Name │ Age │ Admission score │ # → ├──────────────┼─────┼─────────────────┤ # → │ Alice │ 25 │ 95.1 │ # → │ Bob │ 30 │ 87.3 │ # → ├──────────────┼─────┼─────────────────┤ # → │ Carol │ 28 │ 92.1 │ # → │ Michelangelo │ 35 │ 88.0 │ # → └──────────────┴─────┴─────────────────┘ Sorting ------- A table can be sorted on any heading string, and the result is a new table with its rows sorted. from ansitable import ANSITable, Column table = ANSITable( Column("Name", headalign="^", colalign="<"), Column("Age", headalign="^", colalign="<"), Column("Admission score", headalign="^", colalign=">"), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) newtable = table.sort("Age", key=int) newtable.print() # → ┌──────────────┬─────┬─────────────────┐ # → │ Name │ Age │ Admission score │ # → ├──────────────┼─────┼─────────────────┤ # → │ Alice │ 25 │ 95.1 │ # → │ Carol │ 28 │ 92.1 │ # → │ Bob │ 30 │ 87.3 │ # → │ Michelangelo │ 35 │ 88.0 │ # → └──────────────┴─────┴─────────────────┘ Parameters to the ".sort()" method include: * "column" - column name (str) or index (int) * "key" - optional function to transform values before comparison * "reverse" - sort in descending order (default: False) Horizontal rules (added with ".rule()") are silently dropped from sorted output. Color and styling ----------------- If the colored package is installed, you can set foreground/background colors and text styles (bold, reverse, underlined, dim) for header cells, data rows or data cells. See Color reference for a searchable, swatch-illustrated reference of all 256 color names this package accepts (or "colored"'s own list). Header cell color and format ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here we use a dict to set the style for the header cells: bold white text on a dark grey background. from ansitable import ANSITable, Column heading = dict(headstyle="bold", headcolor="white", headbgcolor="grey_53") table = ANSITable( Column("Name", headalign="^", colalign="<", **heading), Column("Age", headalign="^", colalign="<", **heading), Column("Admission score", headalign="^", colalign=">", **heading), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() The color escape characters can't be displayed from an inline documentation code block, they are separately rendered to HTML and included here: Column format ~~~~~~~~~~~~~ Extending the above example so that the *Name* column has its background color set to light blue from ansitable import ANSITable, Column heading = dict(headstyle="bold", headcolor="white", headbgcolor="grey_53") table = ANSITable( Column("Name", headalign="^", colalign="<", colbgcolor="sky_blue_3", **heading), Column("Age", headalign="^", colalign="<", **heading), Column("Admission score", headalign="^", colalign=">", **heading), border="thin") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) table.print() Row format ~~~~~~~~~~ We can apply the format flags to an entire row. Here we set rows where the score is greater than 90 to red background with white text. from ansitable import ANSITable, Column heading = dict(headstyle="bold", headcolor="white", headbgcolor="grey_53") table = ANSITable( Column("Name", headalign="^", colalign="<", colbgcolor="sky_blue_3", **heading), Column("Age", headalign="^", colalign="<", **heading), Column("Admission score", headalign="^", colalign=">", **heading), border="thin") table.row("Alice", 25, 95.1, bgcolor="red_3b", fgcolor="white") table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1, bgcolor="red_3b", fgcolor="white") table.row("Michelangelo", 35, 88.0) table.print() These row formats take priority over formats set for a column. Cell format ~~~~~~~~~~~ We can override the styling of a particular cell using "Cell" instances. Extending the example above, we highlight score cells over 90 with a red background and white text. from ansitable import ANSITable, Column, Cell heading = dict(headstyle="bold", headcolor="white", headbgcolor="grey_53") table = ANSITable( Column("Name", headalign="^", colalign="<", colbgcolor="sky_blue_3", **heading), Column("Age", headalign="^", colalign="<", **heading), Column("Admission score", headalign="^", colalign=">", **heading), border="thin") table.row("Alice", 25, Cell(95.1, bgcolor="red_3b", fgcolor="white")) table.row("Bob", 30, 87.3) table.row("Carol", 28, Cell(92.1, bgcolor="red_3b", fgcolor="white")) table.row("Michelangelo", 35, 88.0) table.print() Cell formats will take priority over formats set for a row or a column. Export formats -------------- Tables can be exported, as a string, in a number of common markup languages for use in documents. Capabilities for alignment, text formatting and color vary across these markup formats. Each format has its own method, and "export()" is a single entry point to all of them, which can also write to a file: table.export("markdown") # returns a string table.export("csv", "results.csv", delimiter=";") table.export(file="table.md") # format from the file extension table.export("rest", sys.stdout) # any open text stream Missing values ("None") are shown as "na_rep", which is blank by default. It can be set for the whole table, "ANSITable(..., na_rep="-")", or per column, "Column("Age", na_rep="n/a")", and the column's format string is not applied to it. Markdown ~~~~~~~~ from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) print(table.markdown()) # → | Name | Age | Admission score | # → | -----------: | --: | --------------: | # → | Alice | 25 | 95.1 | # → | Bob | 30 | 87.3 | # → | Carol | 28 | 92.1 | # → | Michelangelo | 35 | 88.0 | HTML ~~~~ from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) print(table.html()) # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # →
NameAgeAdmission score
Alice2595.1
Bob3087.3
Carol2892.1
Michelangelo3588.0
The table will be rendered according to the document's CSS settings. We can override them for this table by passing additional parameters to "html()" from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) html = table.html( table="border-collapse: collapse; margin: 10px 0; border: 3px solid blue;", th="padding: 8px; border: 1px solid #ddd; font-weight: bold;", td="padding: 8px; border: 1px solid #ddd;", ) print(html) # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # → # →
NameAgeAdmission score
Alice2595.1
Bob3087.3
Carol2892.1
Michelangelo3588.0
reStructuredText (ReST) "simple table" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) print(table.rest()) # → ============ === =============== # → Name Age Admission score # → ============ === =============== # → Alice 25 95.1 # → Bob 30 87.3 # → Carol 28 92.1 # → Michelangelo 35 88.0 # → ============ === =============== LaTeX ~~~~~ from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) print(table.latex()) # → \begin{tabular}{ |r|r|r| }\hline # → \multicolumn{1}{|r|}{Name} & \multicolumn{1}{|r|}{Age} & \multicolumn{1}{|r|}{Admission score}\\\hline\hline # → Alice & 25 & 95.1 \\ # → Bob & 30 & 87.3 \\ # → Carol & 28 & 92.1 \\ # → Michelangelo & 35 & 88.0 \\ # → \hline # → \end{tabular} Alignment options are supported. Wikitable (Wikipedia) ~~~~~~~~~~~~~~~~~~~~~ from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) print(table.wikitable()) # → {| class="wikitable" col1right col2right col3right # → |- # → ! Name !! Age !! Admission score # → |- # → | Alice || 25 || 95.1 # → |- # → | Bob || 30 || 87.3 # → |- # → | Carol || 28 || 92.1 # → |- # → | Michelangelo || 35 || 88.0 # → |} CSV ~~~ from ansitable import ANSITable table = ANSITable("Name", "Age", "Admission score") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) print(table.csv()) # → Name,Age,Admission score # → Alice,25,95.1 # → Bob,30,87.3 # → Carol,28,92.1 # → Michelangelo,35,88.0 Matrices ======== Display NumPy arrays as formatted matrices: from ansitable import ANSIMatrix import numpy as np np.random.seed(42) formatter = ANSIMatrix(style='thick') m = np.random.rand(4, 4) - 0.5 formatter.print(m) # → ┏ ┓ # → ┃-0.125 0.451 0.232 0.0987 ┃ # → ┃-0.344 -0.344 -0.442 0.366 ┃ # → ┃ 0.101 0.208 -0.479 0.47 ┃ # → ┃ 0.332 -0.288 -0.318 -0.317 ┃ # → ┗ ┛ Add superscript and subscript suffixes: from ansitable import ANSIMatrix import numpy as np np.random.seed(42) formatter = ANSIMatrix(style='thick') m = np.random.rand(4, 4) - 0.5 formatter.print(m, suffix_super='T', suffix_sub='3') # → ┏ ┓T # → ┃-0.125 0.451 0.232 0.0987 ┃ # → ┃-0.344 -0.344 -0.442 0.366 ┃ # → ┃ 0.101 0.208 -0.479 0.47 ┃ # → ┃ 0.332 -0.288 -0.318 -0.317 ┃ # → ┗ ┛3 Pandas integration ================== Convert Pandas "DataFrames" to "ANSITable": import pandas as pd from ansitable import ANSITable df = pd.DataFrame({"calories": [420, 380, 390], "duration": [50, 40, 45]}) table = ANSITable.Pandas(df, border="thin") table.print() # → ┌──────────┬──────────┐ # → │ calories │ duration │ # → ├──────────┼──────────┤ # → │ 420 │ 50 │ # → │ 380 │ 40 │ # → │ 390 │ 45 │ # → └──────────┴──────────┘ Convert "ANSITable" back to "DataFrame": from ansitable import ANSITable import pandas as pd table = ANSITable("Name", "Age", "Admission score", border="ascii") table.row("Alice", 25, 95.1) table.row("Bob", 30, 87.3) table.row("Carol", 28, 92.1) table.row("Michelangelo", 35, 88.0) df = table.pandas() print(df) # → Name Age Admission_score # → 0 Alice 25 95.1 # → 1 Bob 30 87.3 # → 2 Carol 28 92.1 # → 3 Michelangelo 35 88.0 Column names are converted to valid Python identifiers (spaces → underscores), allowing attribute access like "df.Admission_score". Disable this with "underscores=False". ======================================================================== Page: https://petercorke.github.io/ansitable/table.html ======================================================================== Table classes ************* This class creates a table that can be pretty printed in any terminal that supports ANSI escape sequences. Creating a table ================ class ansitable.ANSITable(*pos, colsep=1, offset=0, border=None, bordercolor=None, ellipsis=True, columns=None, header=True, color=True, na_rep='') Bases: "object" __init__(*pos, colsep=1, offset=0, border=None, bordercolor=None, ellipsis=True, columns=None, header=True, color=True, na_rep='') Create a table object Parameters: * **colsep** (int) -- Blank padding on each side of column separator, defaults to 1 * **offset** (int) -- Horizontal offset of the whole table, defaults to 0 * **border** (Border | None) -- Type of border, see table below, defaults to None * **bordercolor** (str | None) -- Name of color to draw border in, defaults to None * **ellipsis** (bool) -- cells wider than a column's explicit "width" are cut short and shown with an ellipsis, otherwise they are simply cut, defaults to True. Columns without a "width" fit their widest cell and nothing is ever truncated * **columns** (int | None) -- if no positional column names/"Column" objects are given, create this many empty placeholder columns instead, defaults to None * **header** (bool) -- Show table header, defaults to True * **color** (bool) -- enable color output for this table instance (also gated by global "options()" settings), defaults to True * **na_rep** (str) -- text shown for a missing value ("None"), the column's "fmt" is not applied to it. Can be overridden per column with "Column"'s "na_rep", defaults to "" Raises: * **TypeError** -- if a positional argument is not a "str" or "Column" * **ValueError** -- if bordercolor is not a valid color A table can be created in several different ways: table = ANSITable("col1", "column 2 has a big header", "column 3") table = ANSITable( Column("col1"), Column("column 2 has a big header", "{:.3g}"), Column("column 3", "{:-10.4f}") ) table = ANSITable() table.addcolumn("col1") table.addcolumn("column 2 has a big header", fmt="{:.3g}") table.addcolumn("column 3", fmt="{:-10.4f}") The first option is quick and easy, and by default both header and column data are right-aligned. Formatting options like "fmt" need the second or third form, using "Column" objects, but header/column alignment can still be set in the quick string form with a leading marker, see "Column" for details: table = ANSITable("{<}col1", "{^}column 2 has a big header", "column 3") left-aligns "col1", centres "column 2 has a big header", and leaves "column 3" at the default right alignment. Add data with "row()" and "rule()". There are two kinds of output: * "print()" writes the table to a terminal (or "file="), and "str(table)" returns the same text. * the exporters return a string with no side effects: "markdown()", "rest()", "csv()", "html()", "latex()", "wikitable()" and "pandas()" (a DataFrame). "export()" is a single entry point to all of these, which can also write to a file. +-------------+------------------------------------------------------------+ | Border | Description | |=============|============================================================| | ascii | Use ASCII +-| characters | +-------------+------------------------------------------------------------+ | thin | Use ANSI thin box-drawing characters | +-------------+------------------------------------------------------------+ | round | Use ANSI thin box-drawing characters with rounded corners | +-------------+------------------------------------------------------------+ | thick | Use ANSI thick box-drawing characters | +-------------+------------------------------------------------------------+ | double | Use ANSI double-line box-drawing characters | +-------------+------------------------------------------------------------+ addcolumn(name, **kwargs) Add a column to the table Parameters: **name** ("str") -- column heading Return type: "None" An alternative way to create a table, column at a time. Example: >>> from ansitable import ANSITable >>> table = ANSITable() >>> table.addcolumn("col1") >>> table.addcolumn("column 2 has a big header", fmt="{:.3g}") >>> table.addcolumn("column 3", fmt="{:-10.4f}") Note: Additional arguments are passed directly to "Column". static Pandas(df, **kwargs) Create an ANSITable from a Pandas dataframe Parameters: * **df** ("DataFrame") -- Pandas dataframe * **kwargs** ("Any") -- additional arguments to pass to the ANSITable constructor Return type: "ANSITable" Returns: an ansitable object Example: >>> import pandas as pd >>> from ansitable import ANSITable >>> df = pd.DataFrame({"calories": [420, 380, 390], "duration": [50, 40, 45]}) >>> table = ANSITable.Pandas(df, border="thin") >>> table.print() ┌──────────┬──────────┐ │ calories │ duration │ ├──────────┼──────────┤ │ 420 │ 50 │ │ 380 │ 40 │ │ 390 │ 45 │ └──────────┴──────────┘ Note: * options for header and column alignment and format are not supported class ansitable.Column(name, fmt='{}', width=None, colcolor=None, colbgcolor=None, colstyle=None, colalign='>', headcolor=None, headbgcolor=None, headstyle=None, headalign='>', na_rep=None) Bases: "object" __init__(name, fmt='{}', width=None, colcolor=None, colbgcolor=None, colstyle=None, colalign='>', headcolor=None, headbgcolor=None, headstyle=None, headalign='>', na_rep=None) Create a table column Parameters: * **name** (str) -- Name of column, also the column heading. May begin with an alignment shorthand marker, see below, defaults to right-aligned * **fmt** (str | Callable[[Any], str] | None) -- Python format string, defaults to "{}" * **width** (int | None) -- Column width, defaults to auto- fit * **colcolor** (str | None) -- Color of column text, defaults to None * **colbgcolor** (str | None) -- Color of column background, defaults to None * **colstyle** (Style | None) -- Column text style, see table below, defaults to None * **colalign** (Align) -- Column data alignment, see table below, defaults to ">" * **headcolor** (str | None) -- Color of heading text, defaults to None * **headbgcolor** (str | None) -- Color of heading background, defaults to None * **headstyle** (Style | None) -- Heading text style, see table below, defaults to None * **headalign** (Align | None) -- Heading text alignment, see table below, defaults to ">" * **na_rep** (str | None) -- Text shown for a missing value ("None") in this column, "fmt" is not applied to it. Defaults to None, which uses the table's "na_rep" Raises: **ValueError** -- if a color or style argument is not valid The "Column" object can passed to the "ANSITable" constructor or to "addcolumn()" to specify the format of a column in a table. For header or data cell alignment: +-------------+-------------------------+ | Alignment | Description | |=============|=========================| | "<" | Left | +-------------+-------------------------+ | "^" | Centre | +-------------+-------------------------+ | ">" | Right (default) | +-------------+-------------------------+ For header or data cell alignment text style: +-------------+-----------------------------------------------+ | Style | Description | |=============|===============================================| | bold | bold font | +-------------+-----------------------------------------------+ | dim | low brightness font | +-------------+-----------------------------------------------+ | underlined | text is underlined | +-------------+-----------------------------------------------+ | blink | text is blinking | +-------------+-----------------------------------------------+ | reverse | text and background colors are reversed | +-------------+-----------------------------------------------+ The implementation of these options depends heavily on the terminal emulator used. Alignment shorthand ------------------- "name" can begin with a marker that sets alignment without needing "colalign"/"headalign" keyword arguments, or a full "Column" object -- handy when using "ANSITable"'s quick string- based constructor: * ""{X}Name"" sets both header and column alignment to "X" * ""{XY}Name"" sets header alignment to "X" and column alignment to "Y" where "X"/"Y" are one of ""<"", ""^"", "">"", e.g. "Column("{<^}Name")" left-aligns the header and centres the column data. An explicit "colalign"/"headalign" argument takes precedence over the marker for that axis. A name that must literally start with "{" (and isn't meant as a marker) needs a single leading backslash in the resulting string *value*. "\{" is not itself a valid Python escape sequence, so in ordinary (non-raw) source that means doubling the backslash, e.g. "Column("\\{note}")"; with a raw string it's just "Column(r"\{note}")". Either way, the column's name is ""{note}"". Anything else in the name is left untouched -- there's nothing else to escape. name: str fmt: str | Callable[[Any], str] | None formatted: list[str | None] fgcolor: list[str | None] bgcolor: list[str | None] style: list[Style | None] table: ANSITable | None colcolor: str | None colbgcolor: str | None colstyle: Style | None colalign: Align headcolor: str | None headbgcolor: str | None headstyle: Style | None headalign: Align width: int | None maxwidth: int class ansitable.Cell(text, fgcolor=None, bgcolor=None, style=None) Bases: "object" __init__(text, fgcolor=None, bgcolor=None, style=None) Override the color and style of a cell Parameters: * **text** (Any) -- cell text, converted to "str" if not already * **fgcolor** (str | None) -- foreground color, defaults to None * **bgcolor** (str | None) -- background color, defaults to None * **style** (Style | None) -- text style, one of ""bold"", ""dim"", ""underlined"", ""blink"", ""reverse"", defaults to None Raises: **ValueError** -- if fgcolor, bgcolor, or style is not valid Example: >>> from ansitable import ANSITable, Cell >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row(Cell("ccccccc", bgcolor="red"), 8.8, -9) >>> table.print() col1 column 2 has a big header column 3 aaaaaaaaa 2.2 3 bbbbbbbbbbbbb -5.5 6 ccccccc 8.8 -9 Will print a table with the first cell in the last row having a red background. The colors and style override those specified when the column was created or specified for a row. text: str fgcolor: str | None bgcolor: str | None style: Style | None column: Column | None row: int | None Adding a row ============ class ansitable.ANSITable(*pos, colsep=1, offset=0, border=None, bordercolor=None, ellipsis=True, columns=None, header=True, color=True, na_rep='') Bases: "object" row(*values, fgcolor=None, bgcolor=None, style=None) Add a row of data Parameters: * **values** (Any) -- data items for the row. These can be of any type that can be converted to a string for display, eg. numbers, strings or objects with a "__str__" method. The "Cell" encapsulates a value and allows the color or style defaults of the row or column to be overriden. * **fgcolor** (str | None) -- foreground color override for all columns in the row, defaults to None * **bgcolor** (str | None) -- background color override for all columns in the row, defaults to None * **style** (Style | None) -- style override for all columns in the row, defaults to None Raises: **ValueError** -- invalid format string for the data provided, or fgcolor, bgcolor, style, or an inline ""<>"" specifier is not valid Return type: None "table.row(d1, d2, ... dN)" add data items that comprise a row of the table. "N" is the number of columns. The data items can be any type, but the format string specified at table creation must be compatible. The column data is formatted with the color and style given when the "Column" was created, but it can be overridden for a specific row by specifying the options "fgcolor", "bgcolor", or "style". "Cell" overrides the color and style of a cell specified for a column and a row. rule() Add a horizontal rule to the table This is a horizontal line across all columns, used to delineate parts of the table. Return type: "None" Display a table =============== class ansitable.ANSITable(*pos, colsep=1, offset=0, border=None, bordercolor=None, ellipsis=True, columns=None, header=True, color=True, na_rep='') Bases: "object" print(file=None) Print the table Parameters: **file** (TextIO | None) -- Print the table to this file, defaults to stdout Return type: None Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3", border="ascii") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> table.print() +---------------+---------------------------+----------+ | col1 | column 2 has a big header | column 3 | +---------------+---------------------------+----------+ | aaaaaaaaa | 2.2 | 3 | | bbbbbbbbbbbbb | -5.5 | 6 | | ccccccc | 8.8 | -9 | +---------------+---------------------------+----------+ __str__() Output the table as a string Return type: "str" Returns: ANSI string Sorting tables ============== class ansitable.ANSITable(*pos, colsep=1, offset=0, border=None, bordercolor=None, ellipsis=True, columns=None, header=True, color=True, na_rep='') Bases: "object" sort(column, key=None, reverse=False) Sort the table rows by a column, in place Parameters: * **column** (str | int) -- column to sort by, either the column name or its zero-based index * **key** (Callable[[str], Any] | None) -- callable applied to each formatted cell value before comparison, defaults to None (lexicographic order on the formatted string) * **reverse** (bool) -- sort in descending order, defaults to False Raises: * **ValueError** -- if "column" is a string that does not match any column name * **IndexError** -- if "column" is an integer index out of range Return type: ANSITable Returns: the table, to allow chaining Rows inserted with "rule()" (horizontal rules) are silently dropped from the sorted output, as they have no meaningful position after reordering. Example: >>> from ansitable import ANSITable >>> table = ANSITable("name", "score") >>> table.row("alice", 3) >>> table.row("bob", 1) >>> table.row("carol", 2) >>> table.sort("score", key=int) ANSITable: 3 x 2: name; score >>> table.print() name score bob 1 carol 2 alice 3 Render in markup formats ======================== These methods are used to export an ANSI table to different markup languages. class ansitable.table.ANSITable(*pos, colsep=1, offset=0, border=None, bordercolor=None, ellipsis=True, columns=None, header=True, color=True, na_rep='') Bases: "object" export(format=None, file=None, **kwargs) Export the table in the given format Parameters: * **format** (ExportFormat | None) -- output format, one of ""text"", ""markdown"", ""rest"", ""csv"", ""html"", ""latex"" or ""wikitable"". If None it is inferred from the extension of "file" * **file** (str | os.PathLike[str] | TextIO | None) -- file name, "Path" or open text stream to write to, defaults to None which returns the text instead * **kwargs** (Any) -- passed to the exporter method, eg. "delimiter" for ""csv"" Raises: **ValueError** -- if the format is unknown or cannot be inferred Return type: str | None Returns: the exported text if "file" is None, otherwise None This is a single entry point to the output methods "__str__()", "markdown()", "rest()", "csv()", "html()", "latex()" and "wikitable()". A file name is opened for writing as UTF-8 and closed, a stream is written to but left open. Example: table.export("markdown") # returns a string table.export("csv", "results.csv", delimiter=";") table.export(file="table.md") # format from the extension table.export("rest", sys.stdout) Note: * ""text"" is the same as "str(table)" and includes ANSI escape codes if color is enabled, use "print()" to display it. * use "pandas()" for a DataFrame. markdown() Output the table in MarkDown markup format Return type: "str" Returns: ASCII markdown text Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> print(table.markdown()) | col1 | column 2 has a big header | column 3 | | ------------: | ------------------------: | -------: | | aaaaaaaaa | 2.2 | 3 | | bbbbbbbbbbbbb | -5.5 | 6 | | ccccccc | 8.8 | -9 | This can be used inside a Jupyter notebook cell to display a table: from IPython.display import Markdown Markdown(table.markdown()) Note: * supports column alignment * does not support header alignment, same as column * rows added with "rule()" are omitted from the output rest() Output the table in ReST "simple table" markup format Return type: "str" Returns: ASCII text for a ReST "simple table" Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> print(table.rest()) ============= ========================= ======== col1 column 2 has a big header column 3 ============= ========================= ======== aaaaaaaaa 2.2 3 bbbbbbbbbbbbb -5.5 6 ccccccc 8.8 -9 ============= ========================= ======== Note: * does not support header or column alignment * rows added with "rule()" are omitted from the output wikitable() Output the table in wikitable markup format This is the markup format for tables in Wikipedia. Return type: "str" Returns: wikitable markup text Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> print(table.wikitable()) {| class="wikitable" col1right col2right col3right |- ! col1 !! column 2 has a big header !! column 3 |- | aaaaaaaaa || 2.2 || 3 |- | bbbbbbbbbbbbb || -5.5 || 6 |- | ccccccc || 8.8 || -9 |} Note: * supports column alignment * does not support header alignment, always centred for "wikitable" class * rows added with "rule()" are omitted from the output html(td='', th='', trd='', trh='', table='') Output the table in HTML format Parameters: * **td** ("str") -- CSS style for table data cells, defaults to "" * **th** ("str") -- CSS style for table header cells, defaults to "" * **trd** ("str") -- CSS style for table data rows, defaults to "" * **trh** ("str") -- CSS style for table header rows, defaults to "" * **table** ("str") -- CSS style for the table, defaults to "" Return type: "str" Returns: table rendered in HTML The table is rendered as a table between "" and "
" tags. Table color and style options are supported. Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> print(table.html())
col1 column 2 has a big header column 3
aaaaaaaaa 2.2 3
bbbbbbbbbbbbb -5.5 6
ccccccc 8.8 -9
CSS options defined in the document will apply. These can be overridden for various table elements by passed arguments strings. For example, to create a simple gridded table: table.html( td="border: 1px solid;", th="border: 1px solid;", table="border-collapse: collapse;", ) The CSS style strings must end with a semi-colon. Warning: "td"/"th"/"trd"/"trh" are concatenated *after* the color and style declarations computed from "fgcolor"/"bgcolor"/ "style" (and their column/header equivalents), all in the same "style" attribute. Within one "style" attribute, the last declaration of a given CSS property wins -- so a "th"/"td" string that itself sets "color"/"background-color" (or the "background" shorthand, which includes "background-color") silently overrides whatever color the table computed, with no error or warning. If a colored header or cell isn't showing the color you set, check whether "th"/"td" is also setting a color for the same cells. Restrict these arguments to properties the table itself never sets (border, padding, font-weight of unstyled cells, etc.) to avoid this. Note: * supports column alignment * supports header alignment * support color and style options in the table * rows added with "rule()" are rendered as a "
" spanning all columns latex() Output the table in LaTeX format Return type: "str" Returns: LaTeX tabular markup Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> print(table.latex()) \begin{tabular}{ |r|r|r| }\hline \multicolumn{1}{|r|}{col1} & \multicolumn{1}{|r|}{column 2 has a big header} & \multicolumn{1}{|r|}{column 3}\\\hline\hline aaaaaaaaa & 2.2 & 3 \\ bbbbbbbbbbbbb & -5.5 & 6 \\ ccccccc & 8.8 & -9 \\ \hline \end{tabular} Note: * supports column alignment * supports header alignment * rows added with "rule()" are rendered as "\\hline" csv(delimiter=',') Output the table in comma separated column (CSV) format Parameters: **delimiter** ("str") -- column delimiter, defaults to "," Return type: "str" Returns: ASCII CSV text Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> print(table.csv()) col1,column 2 has a big header,column 3 aaaaaaaaa,2.2,3 bbbbbbbbbbbbb,-5.5,6 ccccccc,8.8,-9 Note: * does not support header or column alignment * rows added with "rule()" are omitted from the output pandas(underscores=True) Convert the table to a Pandas dataframe Parameters: **underscores** ("bool") -- replace spaces in column names with underscores, defaults to True Return type: "DataFrame" Returns: Pandas dataframe Example: >>> from ansitable import ANSITable >>> table = ANSITable("col1", "column 2 has a big header", "column 3") >>> table.row("aaaaaaaaa", 2.2, 3) >>> table.row("bbbbbbbbbbbbb", -5.5, 6) >>> table.row("ccccccc", 8.8, -9) >>> df = table.pandas() >>> print(df) col1 column_2_has_a_big_header column_3 0 aaaaaaaaa 2.2 3 1 bbbbbbbbbbbbb -5.5 6 2 ccccccc 8.8 -9 Note: * does not support header or column alignment * ANSItable column headings can contain spaces, but Pandas column names with spaces cannot be used as attributes. By default spaces are replaced with underscores, but this can be disabled by passing "underscores=False". * rows added with "rule()" are omitted from the output ======================================================================== Page: https://petercorke.github.io/ansitable/matrix.html ======================================================================== Matrix class ************ This class describes a block diagram, a collection of blocks and wires that can be "executed". class ansitable.table.ANSIMatrix(style='thin', fmt='{:< 10.3g}', squish=100) Bases: "object" __init__(style='thin', fmt='{:< 10.3g}', squish=100) Create a matrix formatter Parameters: * **style** ("Literal"["'ascii'", "'thin'", "'round'", "'thick'", "'double'"]) -- Bracket format, defaults to "thin" * **fmt** ("str") -- number format string, defaults to "{:< 10.3g}" * **squish** ("int") -- elements smaller than this times eps are displayed as zero, defaults to 100 Creates a formatter, or template, for formatting matrices. +-------------+------------------------------------------------------------+ | Border | Description | |=============|============================================================| | ascii | Use ASCII +-| characters | +-------------+------------------------------------------------------------+ | thin | Use ANSI thin box-drawing characters | +-------------+------------------------------------------------------------+ | round | Use ANSI thin box-drawing characters with rounded corners | +-------------+------------------------------------------------------------+ | thick | Use ANSI thick box-drawing characters | +-------------+------------------------------------------------------------+ | double | Use ANSI double-line box-drawing characters | +-------------+------------------------------------------------------------+ Example: >>> from ansitable import ANSIMatrix >>> import numpy as np >>> np.random.seed(0) >>> formatter = ANSIMatrix(style="ascii") >>> m = np.random.rand(4, 4) - 0.5 >>> formatter.print(m) + + | 0.0488 0.215 0.103 0.0449 | |-0.0763 0.146 -0.0624 0.392 | | 0.464 -0.117 0.292 0.0289 | | 0.068 0.426 -0.429 -0.413 | + + str(matrix, suffix_super='', suffix_sub='') Output the table as a string Parameters: * **matrix** (*ndarray**(**n**,**) or **ndarray**(**m**,**n**)*) -- NumPy matrix to format * **suffix_super** ("str") -- Right superscript, defaults to '' * **suffix_sub** ("str") -- Right subscript, defaults to '' Raises: **ValueError** -- if the array has more than 2 dimensions Return type: "str" "suffix_super" is where the transpose, inverse, pseudo-inverse, etc. symbol is shown. "suffix_sub" is where the matrix name is typically shown. Example: >>> from ansitable import ANSIMatrix >>> import numpy as np >>> np.random.seed(0) >>> formatter = ANSIMatrix(style="ascii") >>> m = np.random.rand(4, 4) - 0.5 >>> print(formatter.str(m)) + + | 0.0488 0.215 0.103 0.0449 | |-0.0763 0.146 -0.0624 0.392 | | 0.464 -0.117 0.292 0.0289 | | 0.068 0.426 -0.429 -0.413 | + + print(matrix, *pos, file=None, **kwargs) Print the matrix Parameters: **file** (TextIO | None) -- Print the matrix to this file, defaults to stdout Return type: None Note: Accepts the same arguments as "str". Example: >>> from ansitable import ANSIMatrix >>> import numpy as np >>> np.random.seed(0) >>> formatter = ANSIMatrix(style="ascii") >>> m = np.random.rand(4, 4) - 0.5 >>> formatter.print(m, suffix_super="T", suffix_sub="3") + +T | 0.0488 0.215 0.103 0.0449 | |-0.0763 0.146 -0.0624 0.392 | | 0.464 -0.117 0.292 0.0289 | | 0.068 0.426 -0.429 -0.413 | + +3 ======================================================================== Page: https://petercorke.github.io/ansitable/colors.html ======================================================================== Color reference *************** All 256 color names accepted by the colored package -- usable anywhere this package takes a color, e.g. "colcolor", "colbgcolor", "headcolor", "headbgcolor", "bordercolor", and the "fgcolor"/"bgcolor" arguments of "row()" and "Cell". This chart is generated at documentation-build time directly from the installed "colored" package, so it always matches the version of "colored" actually in use. Type in the search box to filter by name, and click a swatch to copy its name.