Skip to content

Commit 75e5b2e

Browse files
committed
adding color map
1 parent df23352 commit 75e5b2e

File tree

9 files changed

+231
-9
lines changed

9 files changed

+231
-9
lines changed

circuitpython_uplot/umap.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# SPDX-FileCopyrightText: 2023 Jose D. Montoya
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
6+
"""
7+
8+
`umap`
9+
================================================================================
10+
11+
CircuitPython color map graph
12+
13+
* Author(s): Jose D. Montoya
14+
15+
16+
"""
17+
try:
18+
from circuitpython_uplot.uplot import Uplot
19+
except ImportError:
20+
pass
21+
22+
from ulab import numpy as np
23+
import displayio
24+
from vectorio import Rectangle
25+
26+
__version__ = "0.0.0+auto.0"
27+
__repo__ = "https://github.com/adafruit/CircuitPython_uplot.git"
28+
29+
30+
# pylint: disable=too-few-public-methods, invalid-name, duplicate-code, too-many-locals, too-many-arguments
31+
# pylint: disable=unused-variable
32+
class umap:
33+
"""
34+
Main class to display different graphics
35+
"""
36+
37+
def __init__(
38+
self,
39+
plot: Uplot,
40+
data_points: np.ndarray,
41+
initial_color: int,
42+
final_color: int,
43+
) -> None:
44+
45+
"""
46+
47+
:param plot: Plot object for the scatter to be drawn
48+
:param data_points: data points to create the color map
49+
:param initial_color: initial color to create the color map
50+
:param final_color: final color to create the color map
51+
52+
"""
53+
54+
xmin = np.min(data_points)
55+
xmax = np.max(data_points)
56+
57+
xnorm = np.array(plot.transform(xmin, xmax, 0.0, 1.0, data_points))
58+
59+
box_iny = data_points.shape[0]
60+
box_inx = data_points.shape[1]
61+
62+
width = plot._newxmax - plot._newxmin
63+
height = plot._newymin - plot._newymax
64+
xdist = width // box_inx
65+
ydist = height // box_iny
66+
67+
palette = displayio.Palette(box_inx * box_iny)
68+
start_color = initial_color
69+
end_color = final_color
70+
counter = 0
71+
for row in xnorm:
72+
for element in row:
73+
palette[counter] = color_fade(start_color, end_color, element)
74+
counter = counter + 1
75+
76+
deltax = plot._newxmin
77+
deltay = plot._newymax
78+
color = 0
79+
for j in range(box_iny):
80+
for i in range(box_inx):
81+
plot.append(
82+
Rectangle(
83+
pixel_shader=palette,
84+
x=deltax,
85+
y=deltay,
86+
width=xdist,
87+
height=ydist,
88+
color_index=color,
89+
)
90+
)
91+
deltax = deltax + xdist
92+
color = color + 1
93+
94+
deltax = plot._newxmin
95+
deltay = deltay + ydist
96+
97+
98+
def color_to_tuple(value):
99+
"""Converts a color from a 24-bit integer to a tuple.
100+
:param value: RGB LED desired value - can be a RGB tuple or a 24-bit integer.
101+
"""
102+
if isinstance(value, tuple):
103+
return value
104+
if isinstance(value, int):
105+
if value >> 24:
106+
raise ValueError("Only bits 0->23 valid for integer input")
107+
r = value >> 16
108+
g = (value >> 8) & 0xFF
109+
b = value & 0xFF
110+
return [r, g, b]
111+
112+
raise ValueError("Color must be a tuple or 24-bit integer value.")
113+
114+
115+
def color_fade(start_color: int, end_color: int, fraction: float):
116+
"""Linear extrapolation of a color between two RGB colors (tuple or 24-bit integer).
117+
:param start_color: starting color
118+
:param end_color: ending color
119+
:param fraction: Floating point number ranging from 0 to 1 indicating what
120+
fraction of interpolation between start_color and end_color.
121+
"""
122+
123+
start_color = color_to_tuple(start_color)
124+
end_color = color_to_tuple(end_color)
125+
if fraction >= 1:
126+
return end_color
127+
if fraction <= 0:
128+
return start_color
129+
130+
faded_color = [0, 0, 0]
131+
for i in range(3):
132+
faded_color[i] = start_color[i] - int(
133+
(start_color[i] - end_color[i]) * fraction
134+
)
135+
return faded_color

docs/api.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11

22
.. If you created a package, create one automodule per module in the package.
33
4-
.. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py)
5-
.. use this format as the module name: "adafruit_foo.foo"
6-
74
.. automodule:: circuitpython_uplot.uplot
85
:members:
96

@@ -21,3 +18,6 @@
2118

2219
.. automodule:: circuitpython_uplot.ufillbetween
2320
:members:
21+
22+
.. automodule:: circuitpython_uplot.umap
23+
:members:

docs/examples.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,13 @@ example of uboxplot integration with uplot
130130
:caption: examples/uplot_uboxplot.py
131131
:linenos:
132132
.. image:: ../docs/uplot_ex16.jpg
133+
134+
Umap Example
135+
---------------------------
136+
137+
umap simple example
138+
139+
.. literalinclude:: ../examples/uplot_umap.py
140+
:caption: examples/uplot_umap.py
141+
:linenos:
142+
.. image:: ../docs/uplot_ex17.jpg

docs/quick_start.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,38 @@ it will fill the area between two curves:
301301
ufillbetween(plot, x, y1, y2)
302302
303303
display.show(plot)
304+
305+
===============
306+
Color Map
307+
===============
308+
309+
Allows you to graph color maps. You just need to give the values in a ulab.numpy.array.
310+
You can choose the initial and final colors for the color map.
311+
312+
.. code-block:: python
313+
314+
import board
315+
from ulab import numpy as np
316+
from circuitpython_uplot.uplot import Uplot
317+
from circuitpython_uplot.umap import umap
318+
319+
320+
display = board.DISPLAY
321+
322+
plot = Uplot(0, 0, display.width, display.height, show_box=False)
323+
324+
x = np.array(
325+
[
326+
[1, 3, 9, 25],
327+
[12, 8, 4, 2],
328+
[18, 3, 7, 5],
329+
[2, 10, 9, 22],
330+
[8, 8, 14, 12],
331+
[3, 13, 17, 15],
332+
],
333+
dtype=np.int16,
334+
)
335+
336+
umap(plot, x, 0xFF0000, 0x0000FF)
337+
338+
display.show(plot)

docs/uplot_ex17.jpg

10 KB
Loading

docs/uplot_ex17.jpg.license

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SPDX-FileCopyrightText: 2023 Jose David M.
2+
3+
SPDX-License-Identifier: MIT

examples/uplot_readme_example.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
# Setting up tick parameters
3535
plot3.tick_params(tickheight=12, tickcolor=0xFF00FF, tickgrid=True)
3636

37-
# Seeting some date to plot
37+
# Seeting some data to plot
3838
x = np.linspace(-4, 4, num=50)
3939
constant = 1.0 / np.sqrt(2 * np.pi)
4040
y = constant * np.exp((-(x**2)) / 2.0)
@@ -53,12 +53,9 @@
5353

5454
plot.append(plot4)
5555

56-
# Setting up the display
57-
5856
plot5 = Uplot(0, 180, 120, 120)
5957

6058
# Setting up tick parameters
61-
6259
plot5.axs_params(axstype="cartesian")
6360
a = np.linspace(3, 98)
6461
b = [choice(a) for _ in a]
@@ -93,5 +90,5 @@
9390

9491
plot.append(plot7)
9592

96-
93+
# Plotting and showing the plot
9794
display.show(plot)

examples/uplot_ucartesian_advanced.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
constant = 1.0 / np.sqrt(2 * np.pi)
1818
y = constant * np.exp((-(x**2)) / 2.0)
1919

20-
# Drawing the graphm
20+
# Drawing the graph
2121
ucartesian(plot, x, y, rangex=[-5, 5], rangey=[0, 1], line_color=0xFF0000)
2222

2323
# Creating some points to graph
@@ -26,6 +26,9 @@
2626
y = constant * np.exp((-(x**2)) / 2.0)
2727
ucartesian(plot, x, y, rangex=[-5, 5], rangey=[0, 1], line_color=0x00FF00)
2828

29+
# Plotting and showing the plot
2930
display.show(plot)
31+
32+
# Adding some wait time
3033
while True:
3134
time.sleep(1)

examples/uplot_umap.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Jose D. Montoya
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import board
7+
from ulab import numpy as np
8+
from circuitpython_uplot.uplot import Uplot
9+
from circuitpython_uplot.umap import umap
10+
11+
12+
# Setting up the display
13+
display = board.DISPLAY
14+
15+
# Adding the plot area
16+
plot = Uplot(0, 0, display.width, display.height, show_box=False)
17+
18+
# Setting some date to plot
19+
x = np.array(
20+
[
21+
[1, 3, 9, 25],
22+
[12, 8, 4, 2],
23+
[18, 3, 7, 5],
24+
[2, 10, 9, 22],
25+
[8, 8, 14, 12],
26+
[3, 13, 17, 15],
27+
],
28+
dtype=np.int16,
29+
)
30+
31+
# Plotting and showing the plot
32+
umap(plot, x, 0xFF0000, 0x0000FF)
33+
34+
# Plotting and showing the plot
35+
display.show(plot)
36+
37+
# Adding some wait time
38+
while True:
39+
time.sleep(1)

0 commit comments

Comments
 (0)