matthewplotlib

matthewplotlib.core

@dataclasses.dataclass
class CharArray:

A grid of possibly-coloured characters comprising a plot. For internal use.

Fields:

  • codes: uint32[h,w]. Unicode code point for the character.
  • fg: bool[h,w]. Whether to use a custom foreground color.
  • fg_rgb: uint8[h,w,3]. (If fg) RGB for custom foreground color.
  • bg: bool[h,w]. Whether to use a custom background color.
  • bg_rgb: uint8[h,w,3]. (If bg) RGB for custom background color.
CharArray( codes: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], fg: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], fg_rgb: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], bg: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], bg_rgb: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]])
codes: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
fg: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
fg_rgb: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
bg: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
bg_rgb: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
height: int
width: int
@staticmethod
def from_codes( codes: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], fgcolor: ColorLike | None, bgcolor: ColorLike | None) -> CharArray:
@staticmethod
def from_size( height: int, width: int, fgcolor: ColorLike | None = None, bgcolor: ColorLike | None = None) -> CharArray:
def pad( self: Self, above: int = 0, below: int = 0, left: int = 0, right: int = 0, fgcolor: ColorLike | None = None, bgcolor: ColorLike | None = None) -> CharArray:
@staticmethod
def map( f: Callable[[list[numpy.ndarray[tuple[Any, ...], numpy.dtype[~_ScalarT]]]], numpy.ndarray[tuple[Any, ...], numpy.dtype[~_ScalarT]]], charss: list[CharArray]) -> CharArray:
def isblank( self: Self) -> numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]:

True where the character has no visible content.

def isnonblank( self: Self) -> numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]:

True where the character has visible content.

def to_ansi_str(self: Self) -> str:

Render a CharArray as a sequence of characters and ANSI control codes (merging codes where possible).

def to_plain_str(self: Self) -> str:

Render a CharArray as a sequence of characters without colour.

def to_rgba_array(self: Self, bgcolor: ColorLike | None = None) -> numpy.ndarray:

Convert a CharArray to an RGBA image array

def to_bit_array(self: Self) -> numpy.ndarray:

Convert a CharArray to an bitmap image array

def ords(chrs):

Convert a string or list of characters to a list of unicode code points.

BRAILLE_MAP = array([[0, 3], [1, 4], [2, 5], [6, 7]], dtype=uint8)
def unicode_braille_array( dots: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], dotc: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]] | None = None, dotw: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]] | None = None, fgcolor: ColorLike | None = None, bgcolor: ColorLike | None = None) -> CharArray:

Turns a H by W array of dots into a h=ceil(H/4) by w=ceil(W/2) array of braille Unicode characters.

Inputs:

  • dots: bool[H, W]. Array of booleans or counts. Dots are placed where this array contains nonzero.
  • dotc: optional uint8[H, W, RGB]. Array of colours to use for the fg of each dot. Where multiple dots are coloured within one one character, mixes the colours according to dotw.
  • dotw: optional float[H, W]. Weights for combining colors when multiple dots occur in one cell. If not provided, combine uniformly. If dotc is not provided, this is not used.
  • fgcolor: optional ColorLike. Foreground color used for all braille characters. Overrides dotc if both are provided.
  • bgcolor: optional ColorLike. Background color used for all characters.

Returns:

  • chars: CharArray. An array of Braille characters with h rows and w columns.

An illustrated example, not including colour combination, is as follows:

Start with an array. Assume height is divisible by 4 and width divisible by
2, otherwise pad with 0s until that is the case.
    ____
   [1  0] 0  1  0  1  1  1  1  0  1  0  0  0  0  1  0  0  0  0  0  1  1  0
   [1  0] 0  1  0  1  0  0  0  0  1  0  0  0  0  1  0  0  0  0  1  0  0  1
 .-[1  0] 0  1  0  1  0  0  0  0  1  0  0  0  0  1  0  0  0  0  1  0  0  1
 | [1__0] 0  1  0  1  0  0  0  0  1  0  0  0  0  1  0  0  0  0  1  0  0  1
 |  1  1  1  1  0  1  1  1  1  0  1  0  0  0  0  1  0  0  0  0  1  0  0  1
 |  1  0  0  1  0  1  0  0  0  0  1  0  0  0  0  1  0  0  0  0  1  0  0  1
 |  1  0  0  1  0  1  0  0  0  0  1  0  0  0  0  1  0  0  0  0  1  0  0  1
 |  1  0  0  1  0  1  1  1  1  0  1  1  1  1  0  1  1  1  1  0  0  1  1  0
 |
 | take each 4x2 subarray and ...
 |                                                               braille
 | identify the 4x2 bits with the                                unicode
 | eight numbered braille dots:                                  start pt
 |                                                               |
 |  (dot 1) 1 0 (dot 4)     convert to                           v
 `> (dot 2) 1 0 (dot 5) -----------------> 0 b 0 1 0 0 0 1 1 1 + 0x2800 -.
    (dot 3) 1 0 (dot 6)    braille code        | | | | | | | |           |
    (dot 7) 1 0 (dot 8)                    dot 8 7 6 5 4 3 2 1           |
                                                                         |
  convert the braille code to a unicode character and collate into array |
 .-----------------------------------------------------------------------'
 |  '''
 `->⡇⢸⢸⠉⠁⡇⠀⢸⠀⠀⡎⢱  (Note: this function returns a CharArray, use
    ⡏⢹⢸⣉⡁⣇⣀⢸⣀⡀⢇⡸  .to_plain_str() to get a string.)
    '''
PARTIAL_BLOCKS_ROW = [32, 9615, 9614, 9613, 9612, 9611, 9610, 9609, 9608]
def unicode_bar( proportion: float, width: int, height: int = 1, fgcolor: ColorLike | None = None, bgcolor: ColorLike | None = None) -> CharArray:

Generates a Unicode progress bar as a list of characters.

This function creates a fixed-width left-to-right bar using Unicode block elements to represent the proportion rounded down to nearest 1/8th of a block.

Inputs:

  • proportion: float. The fraction of the bar to fill. Should be between 0.0 and 1.0 inclusive.
  • width: int (positive). The width of the full bar in characters.
  • height: int (positive, default 1). The number of rows that the bar takes up.
  • fgcolor: optional ColorLike. Foreground color used for the progress bar characters.
  • bgcolor: optional ColorLike. Background color used for the progress bar remainder.

Returns:

  • chars: CharArray A character array representing the bar.

Examples:

>>> unicode_bar(0.5, 10).to_plain_str()
'█████     '
>>> unicode_bar(0.625, 10).to_plain_str()
'██████▎   '

PARTIAL_BLOCKS_COL = [32, 9601, 9602, 9603, 9604, 9605, 9606, 9607, 9608]
def unicode_col( proportion: float, height: int, width: int = 1, fgcolor: ColorLike | None = None, bgcolor: ColorLike | None = None) -> CharArray:

Generates a Unicode progress column as a list of characters.

This function creates a fixed-height column using Unicode block elements to
represent a proportion rounded down to nearest 1/8th of a block. The list
goes from the top of the bar to the bottom, but the bar grows from the
bottom towards the top.

Inputs:

* proportion: float.
    The fraction of the column to fill. Should be between 0.0 and 1.0
    inclusive.
* height: int (positive).
    The height of the full bar in characters.
* width: int (positive, default 1).
    The number of columns that the bar takes up.
* fgcolor: optional ColorLike.
    Foreground color used for the progress bar characters.
* bgcolor: optional ColorLike.
    Background color used for the progress bar remainder.

Returns:

* chars: CharArray
    A char array representing the column.

Examples:
    >>> unicode_col(0.5, 3).to_plain_str()
    ' 
▄
█'

class BoxStyle(builtins.str, enum.Enum):

A string enum defining preset styles for the border plot.

Each style is a string of eight characters representing the border elements.

Available Styles:

  • LIGHT: A standard, single-line border.
  • HEAVY: A thicker, bold border.
  • DOUBLE: A double-line border.
  • DASHED: A dashed single-line border.
  • BLANK: An invisible border (easily add 1-width padding).
  • ROUND: A single-line border with rounded corners.
  • BUMPER: A single-line border with corners made of blocks.
  • BLOCK1: A blocky border with half-width left and right walls.
  • BLOCK2: A uniform blocky border.
  • TIGER1: A stripy block border.
  • TIGER2: An alternative stripy block border.
  • LIGHTX: A light border with axis ticks.
  • HEAVYX: A heavy border with axis ticks.
  • LOWERX: A partial border with axis ticks.

Demo:

┌──────┐ ┏━━━━━━┓ ╔══════╗ ┌╌╌╌╌╌╌┐ ⡤⠤⠤⠤⠤⠤⠤⢤ ╭──────╮
│LIGHT │ ┃HEAVY ┃ ║DOUBLE║ ┊DASHED┊ ⡇DOTTED⢸ │ROUND │
└──────┘ ┗━━━━━━┛ ╚══════╝ └╌╌╌╌╌╌┘ ⠓⠒⠒⠒⠒⠒⠒⠚ ╰──────╯
         ▛──────▜ ▛▀▀▀▀▀▀▜ █▀▀▀▀▀▀█ ▞▝▝▝▝▝▝▝ ▘▘▘▘▘▘▘▚
 BLANK   │BUMPER│ ▌BLOCK1▐ █BLOCK2█ ▖TIGER1▝ ▘TIGER2▗
         ▙──────▟ ▙▄▄▄▄▄▄▟ █▄▄▄▄▄▄█ ▖▖▖▖▖▖▖▞ ▚▗▗▗▗▗▗▗
┬──────┐ ┲━━━━━━┓ ╷        
│LIGHTX│ ┃HEAVYX┃ │LOWERX  
┼──────┤ ╄━━━━━━┩ ┼──────╴ 

TODO:

  • It might make sense to consider borders with two characters on the left and right sides of the contents. Would open up new design possibilities.
LIGHT = <BoxStyle.LIGHT: '┌─┐││└─┘'>
HEAVY = <BoxStyle.HEAVY: '┏━┓┃┃┗━┛'>
DOUBLE = <BoxStyle.DOUBLE: '╔═╗║║╚═╝'>
DASHED = <BoxStyle.DASHED: '┌╌┐┊┊└╌┘'>
DOTTED = <BoxStyle.DOTTED: '⡤⠤⢤⢸⡇⠓⠒⠚'>
ROUND = <BoxStyle.ROUND: '╭─╮││╰─╯'>
BLANK = <BoxStyle.BLANK: ' '>
BUMPER = <BoxStyle.BUMPER: '▛─▜││▙─▟'>
BLOCK1 = <BoxStyle.BLOCK1: '▛▀▜▐▌▙▄▟'>
BLOCK2 = <BoxStyle.BLOCK2: '█▀████▄█'>
TIGER1 = <BoxStyle.TIGER1: '▞▝▝▝▖▖▖▞'>
TIGER2 = <BoxStyle.TIGER2: '▘▘▚▘▘▚▗▗'>
LIGHTX = <BoxStyle.LIGHTX: '┬─┐││┼─┤'>
HEAVYX = <BoxStyle.HEAVYX: '┲━┓┃┃╄━┩'>
LOWERX = <BoxStyle.LOWERX: '╷ │┼─╴'>
def unicode_box( chars: CharArray, style: BoxStyle, fgcolor: ColorLike | None = None, bgcolor: ColorLike | None = None, title: str = '') -> CharArray:

Wrap a character array in an outline of box drawing characters.

def unicode_image( image: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]) -> CharArray:

Convert an RGB image into an array of coloured Unicode half-block characters representing the pixels of the image.

Inputs:

  • image: u8[h, w, rgb]. The pixels of the image.

Returns:

  • chars: CharArray[ceil(h/2), w]. The array of coloured half-block characters. If the image has odd height, the bottom half of the final row is set to the default background colour.