Skip to content

pixel_matrix

The module containing all the widgets that can be used to display pixel-based data.

DensePixelMatrix

Bases: PixelMatrix

A more dense (2x) PixelMatrix.

Due to each pixel only occupying 1/2 characters in height, accurately determining selected_pixel is impossible, thus the functionality does not exist here.

Source code in pytermgui/widgets/pixel_matrix.py
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
class DensePixelMatrix(PixelMatrix):
    """A more dense (2x) PixelMatrix.

    Due to each pixel only occupying 1/2 characters in height, accurately
    determining selected_pixel is impossible, thus the functionality does
    not exist here.
    """

    def __init__(self, width: int, height: int, default: str = "", **attrs) -> None:
        """Initializes DensePixelMatrix.

        Args:
            width: The width of the matrix.
            height: The height of the matrix.
            default: The default color to use to initialize the matrix with.
        """

        super().__init__(width, height, default, **attrs)

        self.width = width // 2

    def handle_mouse(self, event: MouseEvent) -> bool:
        """As mentioned in the class documentation, mouse handling is disabled here."""

        return False

    def build(self) -> list[str]:
        """Builds the image pixels, using half-block characters.

        Returns:
            The lines that this object will return, until a subsequent `build` call.
            These lines are stored in the `self._lines` variable.
        """

        lines = []
        lines_to_zip: list[list[str]] = []
        for row in self._matrix:
            lines_to_zip.append(row)
            if len(lines_to_zip) != 2:
                continue

            line = ""
            top_row, bottom_row = lines_to_zip[0], lines_to_zip[1]
            for bottom, top in zip(bottom_row, top_row):
                if len(top) + len(bottom) == 0:
                    line += " "
                    continue

                if bottom == "":
                    line += tim.parse(f"[{top}]▀")
                    continue

                markup_str = "@" + top + " " if len(top) > 0 else ""

                markup_str += bottom
                line += tim.parse(f"[{markup_str}]▄")

            lines.append(line)
            lines_to_zip = []

        self._lines = lines
        self._update_dimensions(lines)

        return lines

__init__(width, height, default='', attrs)

Initializes DensePixelMatrix.

Parameters:

Name Type Description Default
width int

The width of the matrix.

required
height int

The height of the matrix.

required
default str

The default color to use to initialize the matrix with.

''
Source code in pytermgui/widgets/pixel_matrix.py
162
163
164
165
166
167
168
169
170
171
172
173
def __init__(self, width: int, height: int, default: str = "", **attrs) -> None:
    """Initializes DensePixelMatrix.

    Args:
        width: The width of the matrix.
        height: The height of the matrix.
        default: The default color to use to initialize the matrix with.
    """

    super().__init__(width, height, default, **attrs)

    self.width = width // 2

build()

Builds the image pixels, using half-block characters.

Returns:

Type Description
list[str]

The lines that this object will return, until a subsequent build call.

list[str]

These lines are stored in the self._lines variable.

Source code in pytermgui/widgets/pixel_matrix.py
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
def build(self) -> list[str]:
    """Builds the image pixels, using half-block characters.

    Returns:
        The lines that this object will return, until a subsequent `build` call.
        These lines are stored in the `self._lines` variable.
    """

    lines = []
    lines_to_zip: list[list[str]] = []
    for row in self._matrix:
        lines_to_zip.append(row)
        if len(lines_to_zip) != 2:
            continue

        line = ""
        top_row, bottom_row = lines_to_zip[0], lines_to_zip[1]
        for bottom, top in zip(bottom_row, top_row):
            if len(top) + len(bottom) == 0:
                line += " "
                continue

            if bottom == "":
                line += tim.parse(f"[{top}]▀")
                continue

            markup_str = "@" + top + " " if len(top) > 0 else ""

            markup_str += bottom
            line += tim.parse(f"[{markup_str}]▄")

        lines.append(line)
        lines_to_zip = []

    self._lines = lines
    self._update_dimensions(lines)

    return lines

handle_mouse(event)

As mentioned in the class documentation, mouse handling is disabled here.

Source code in pytermgui/widgets/pixel_matrix.py
175
176
177
178
def handle_mouse(self, event: MouseEvent) -> bool:
    """As mentioned in the class documentation, mouse handling is disabled here."""

    return False

PixelMatrix

Bases: Widget

A matrix of pixels.

The way this object should be used is by accessing & modifying the underlying matrix. This can be done using the set & getitem syntacies:

from pytermgui import PixelMatrix

matrix = PixelMatrix(10, 10, default="white")
for y in matrix.rows:
    for x in matrix.columns:
        matrix[y, x] = "black"

The above snippet draws a black diagonal going from the top left to bottom right.

Each item of the rows should be a single PyTermGUI-parsable color string. For more information about this, see pytermgui.ansi_interface.Color.

Source code in pytermgui/widgets/pixel_matrix.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
class PixelMatrix(Widget):
    """A matrix of pixels.

    The way this object should be used is by accessing & modifying
    the underlying matrix. This can be done using the set & getitem
    syntacies:

    ```python3
    from pytermgui import PixelMatrix

    matrix = PixelMatrix(10, 10, default="white")
    for y in matrix.rows:
        for x in matrix.columns:
            matrix[y, x] = "black"
    ```

    The above snippet draws a black diagonal going from the top left
    to bottom right.

    Each item of the rows should be a single PyTermGUI-parsable color
    string. For more information about this, see
    `pytermgui.ansi_interface.Color`.
    """

    selected_pixel: tuple[tuple[int, int], str] | None
    """A tuple of the position & value (color) of the currently hovered pixel."""

    def __init__(
        self, width: int, height: int, default: str = "background", **attrs
    ) -> None:
        """Initializes a PixelMatrix.

        Args:
            width: The amount of columns the matrix will have.
            height: The amount of rows the matrix will have.
            default: The default color to use to initialize the matrix with.
        """

        super().__init__(**attrs)

        self.rows = height
        self.columns = width

        self._matrix = []

        for _ in range(self.rows):
            self._matrix.append([default] * self.columns)

        self.selected_pixel = None
        self.build()

    @classmethod
    def from_matrix(cls, matrix: list[list[str]]) -> PixelMatrix:
        """Creates a PixelMatrix from the given matrix.

        The given matrix should be a list of rows, each containing a number
        of cells. It is optimal for all rows to share the same amount of cells.

        Args:
            matrix: The matrix to use. This is a list of lists of strings
                with each element representing a PyTermGUI-parseable color.

        Returns:
            A new type(self).
        """

        obj = cls(max(len(row) for row in matrix), len(matrix))
        setattr(obj, "_matrix", matrix)
        obj.build()

        return obj

    def _update_dimensions(self, lines: list[str]):
        """Updates the dimensions of this matrix.

        Args:
            lines: A list of lines that the calculations will be based upon.
        """

        self.static_width = max(real_length(line) for line in lines)
        self.height = len(lines)

    def on_hover(self, event: MouseEvent) -> bool:
        """Sets `selected_pixel` to the current pixel."""

        xoffset = event.position[0] - self.pos[0]
        yoffset = event.position[1] - self.pos[1]

        color = self._matrix[yoffset][xoffset // 2]

        self.selected_pixel = ((xoffset // 2, yoffset), color)
        return True

    def get_lines(self) -> list[str]:
        """Returns lines built by the `build` method."""

        return self._lines

    def build(self) -> list[str]:
        """Builds the image pixels.

        Returns:
            The lines that this object will return, until a subsequent `build` call.
            These lines are stored in the `self._lines` variable.
        """

        lines: list[str] = []
        for row in self._matrix:
            line = ""
            for pixel in row:
                if len(pixel) > 0 and pixel != "background":
                    line += f"[@{pixel}]  "
                else:
                    line += "[/ background]  "

            lines.append(tim.parse(line))

        self._lines = lines
        self._update_dimensions(lines)

        return lines

    def __getitem__(self, indices: tuple[int, int]) -> str:
        """Gets a matrix item."""

        posy, posx = indices
        return self._matrix[posy][posx]

    def __setitem__(self, indices: tuple[int, int], value: str) -> None:
        """Sets a matrix item."""

        posy, posx = indices
        self._matrix[posy][posx] = value

__getitem__(indices)

Gets a matrix item.

Source code in pytermgui/widgets/pixel_matrix.py
141
142
143
144
145
def __getitem__(self, indices: tuple[int, int]) -> str:
    """Gets a matrix item."""

    posy, posx = indices
    return self._matrix[posy][posx]

__init__(width, height, default='background', attrs)

Initializes a PixelMatrix.

Parameters:

Name Type Description Default
width int

The amount of columns the matrix will have.

required
height int

The amount of rows the matrix will have.

required
default str

The default color to use to initialize the matrix with.

'background'
Source code in pytermgui/widgets/pixel_matrix.py
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def __init__(
    self, width: int, height: int, default: str = "background", **attrs
) -> None:
    """Initializes a PixelMatrix.

    Args:
        width: The amount of columns the matrix will have.
        height: The amount of rows the matrix will have.
        default: The default color to use to initialize the matrix with.
    """

    super().__init__(**attrs)

    self.rows = height
    self.columns = width

    self._matrix = []

    for _ in range(self.rows):
        self._matrix.append([default] * self.columns)

    self.selected_pixel = None
    self.build()

__setitem__(indices, value)

Sets a matrix item.

Source code in pytermgui/widgets/pixel_matrix.py
147
148
149
150
151
def __setitem__(self, indices: tuple[int, int], value: str) -> None:
    """Sets a matrix item."""

    posy, posx = indices
    self._matrix[posy][posx] = value

build()

Builds the image pixels.

Returns:

Type Description
list[str]

The lines that this object will return, until a subsequent build call.

list[str]

These lines are stored in the self._lines variable.

Source code in pytermgui/widgets/pixel_matrix.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
def build(self) -> list[str]:
    """Builds the image pixels.

    Returns:
        The lines that this object will return, until a subsequent `build` call.
        These lines are stored in the `self._lines` variable.
    """

    lines: list[str] = []
    for row in self._matrix:
        line = ""
        for pixel in row:
            if len(pixel) > 0 and pixel != "background":
                line += f"[@{pixel}]  "
            else:
                line += "[/ background]  "

        lines.append(tim.parse(line))

    self._lines = lines
    self._update_dimensions(lines)

    return lines

from_matrix(matrix) classmethod

Creates a PixelMatrix from the given matrix.

The given matrix should be a list of rows, each containing a number of cells. It is optimal for all rows to share the same amount of cells.

Parameters:

Name Type Description Default
matrix list[list[str]]

The matrix to use. This is a list of lists of strings with each element representing a PyTermGUI-parseable color.

required

Returns:

Type Description
PixelMatrix

A new type(self).

Source code in pytermgui/widgets/pixel_matrix.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
@classmethod
def from_matrix(cls, matrix: list[list[str]]) -> PixelMatrix:
    """Creates a PixelMatrix from the given matrix.

    The given matrix should be a list of rows, each containing a number
    of cells. It is optimal for all rows to share the same amount of cells.

    Args:
        matrix: The matrix to use. This is a list of lists of strings
            with each element representing a PyTermGUI-parseable color.

    Returns:
        A new type(self).
    """

    obj = cls(max(len(row) for row in matrix), len(matrix))
    setattr(obj, "_matrix", matrix)
    obj.build()

    return obj

get_lines()

Returns lines built by the build method.

Source code in pytermgui/widgets/pixel_matrix.py
112
113
114
115
def get_lines(self) -> list[str]:
    """Returns lines built by the `build` method."""

    return self._lines

on_hover(event)

Sets selected_pixel to the current pixel.

Source code in pytermgui/widgets/pixel_matrix.py
101
102
103
104
105
106
107
108
109
110
def on_hover(self, event: MouseEvent) -> bool:
    """Sets `selected_pixel` to the current pixel."""

    xoffset = event.position[0] - self.pos[0]
    yoffset = event.position[1] - self.pos[1]

    color = self._matrix[yoffset][xoffset // 2]

    self.selected_pixel = ((xoffset // 2, yoffset), color)
    return True