Skip to content

Commit 6b07f4d

Browse files
committed
adding scatter_pointers
1 parent 196e7e7 commit 6b07f4d

File tree

7 files changed

+166
-19
lines changed

7 files changed

+166
-19
lines changed

circuitpython_uplot/scatter.py

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@
2323

2424
from ulab import numpy as np
2525
import displayio
26-
from vectorio import Circle
26+
from vectorio import Circle, Polygon
2727

2828
__version__ = "0.0.0+auto.0"
2929
__repo__ = "https://github.com/adafruit/CircuitPython_uplot.git"
3030

3131

32+
_TRIANGLE = [(0, 0), (8, 0), (4, -7)]
33+
_SQUARE = [(0, 0), (6, 0), (6, -6), (0, -6)]
34+
_DIAMOND = [(0, 0), (3, -4), (6, 0), (3, 4)]
35+
36+
3237
class Scatter:
3338
"""
3439
Main class to display different graphics
@@ -42,7 +47,8 @@ def __init__(
4247
rangex: Optional[list] = None,
4348
rangey: Optional[list] = None,
4449
radius: Optional[Union[list, int]] = 3,
45-
circle_color: int = 0xFF905D,
50+
pointer_color: int = 0xFF905D,
51+
pointer: Optional[str] = None,
4652
nudge: bool = True,
4753
) -> None:
4854
"""
@@ -53,6 +59,8 @@ def __init__(
5359
:param list|None rangex: x range limits
5460
:param list|None rangey: y range limits
5561
:param int|list radius: circle radius
62+
:param int pointer_color: pointer color. Default is 0xFF905D
63+
:param str|None pointer: pointer shape.
5664
:param bool nudge: moves the graph a little for better displaying
5765
5866
"""
@@ -61,6 +69,14 @@ def __init__(
6169
else:
6270
nudge_factor = 0
6371

72+
if pointer is None:
73+
self._pointer = "circle"
74+
else:
75+
self._pointer = pointer
76+
77+
self._radius = radius
78+
self._pointer_color = pointer_color
79+
6480
if rangex is None:
6581
xmin = np.min(x) - nudge_factor * (abs(np.max(x) - np.min(x)) / 10)
6682
xmax = np.max(x) + nudge_factor * (abs(np.max(x) - np.min(x)) / 10)
@@ -78,30 +94,73 @@ def __init__(
7894
x = np.array(x)
7995
y = np.array(y)
8096

81-
xnorm = np.array(
97+
self._xnorm = np.array(
8298
plot.transform(xmin, xmax, plot._newxmin, plot._newxmax, x),
8399
dtype=np.int16,
84100
)
85-
ynorm = np.array(
101+
self._ynorm = np.array(
86102
plot.transform(ymin, ymax, plot._newymin, plot._newymax, y),
87103
dtype=np.int16,
88104
)
89105

90-
palette = displayio.Palette(1)
91-
palette[0] = circle_color
106+
self._draw_pointer(plot)
107+
108+
if plot._showticks:
109+
plot._draw_ticks(x, y)
110+
111+
def _draw_pointer(self, plot: Plot) -> None:
112+
"""
113+
114+
:param plot: Plot object for the scatter to be drawn
92115
93-
if isinstance(radius, list):
94-
for i, _ in enumerate(x):
116+
"""
117+
palette = displayio.Palette(1)
118+
palette[0] = self._pointer_color
119+
if isinstance(self._radius, list):
120+
for i, _ in enumerate(self._xnorm):
95121
plot.append(
96122
Circle(
97-
pixel_shader=palette, radius=radius[i], x=xnorm[i], y=ynorm[i]
123+
pixel_shader=palette,
124+
radius=self._radius[i],
125+
x=self._xnorm[i],
126+
y=self._ynorm[i],
98127
)
99128
)
100129
else:
101-
for i, _ in enumerate(x):
102-
plot.append(
103-
Circle(pixel_shader=palette, radius=radius, x=xnorm[i], y=ynorm[i])
104-
)
105-
106-
if plot._showticks:
107-
plot._draw_ticks(x, y)
130+
for i, _ in enumerate(self._xnorm):
131+
if self._pointer == "circle":
132+
plot.append(
133+
Circle(
134+
pixel_shader=palette,
135+
radius=self._radius,
136+
x=self._xnorm[i],
137+
y=self._ynorm[i],
138+
)
139+
)
140+
elif self._pointer == "triangle":
141+
plot.append(
142+
Polygon(
143+
points=_TRIANGLE,
144+
pixel_shader=palette,
145+
x=self._xnorm[i],
146+
y=self._ynorm[i],
147+
)
148+
)
149+
elif self._pointer == "square":
150+
plot.append(
151+
Polygon(
152+
points=_SQUARE,
153+
pixel_shader=palette,
154+
x=self._xnorm[i],
155+
y=self._ynorm[i],
156+
)
157+
)
158+
elif self._pointer == "diamond":
159+
plot.append(
160+
Polygon(
161+
points=_DIAMOND,
162+
pixel_shader=palette,
163+
x=self._xnorm[i],
164+
y=self._ynorm[i],
165+
)
166+
)

docs/examples.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ Scatter plot Example
6161
:lines: 5-
6262
.. image:: ../docs/scatter.jpg
6363

64+
Scatter Circle Pointers with diferent Radius
65+
---------------------------------------------
66+
67+
Example showing how to use different radius in the circle pointers
68+
69+
.. literalinclude:: ../examples/scatter_circle_radius.py
70+
:caption: examples/scatter_circle_radius.py
71+
:lines: 5-
72+
.. image:: ../docs/scatter_circle_radius.jpg
73+
74+
Scatter Pointers Example
75+
----------------------------
76+
77+
Example showing how to use different pointers
78+
79+
.. literalinclude:: ../examples/scatter.py
80+
:caption: examples/scatter.py
81+
:lines: 5-
82+
.. image:: ../docs/scatter_pointers.jpg
83+
6484
Display_shapes Example
6585
-----------------------
6686

docs/quick_start.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ At the moment the following objects can be added to the plot area:
6565
* Bar graph
6666
* Pie Chart
6767
* Colormap
68+
* Polar graph
69+
* SVG Rudimentary support
70+
* Logging graph
6871
* Display_shapes library objects
6972
* Histograms from the uhistogram library
7073
* Boxplots from the uboxplot library
@@ -264,8 +267,8 @@ Creates a scatter plot with x,y data. You can customize the circle diameter if y
264267
265268
There are some parameters that you can customize:
266269
* rangex and rangey: you can specify the ranges of your graph. This allows you to move your graph according to your needs. This parameters only accept lists
267-
* radius: circles radius/radii
268-
* circle_color: you can specify the color in HEX
270+
* radius: circles radius/radii. If a different value is given for each point, the radius should be a list of values. If selected pointer is not a circle, this parameter will be ignored
271+
* pointer_color: you can specify the color in HEX
269272
* nudge: this parameter allows you to move the graph slighty. This is useful when the data start/end in the limits of your range
270273

271274

@@ -275,7 +278,7 @@ There are some parameters that you can customize:
275278
z = [4, 5, 6, 7, 8]
276279
radi = [choice(z) for _ in a]
277280
b = [choice(a) for _ in a]
278-
Scatter(plot, a, b, rangex=[0,210], rangey=[0, 210], radius=radi, circle_color=0xF456F3)
281+
Scatter(plot, a, b, rangex=[0,210], rangey=[0, 210], radius=radi, pointer_color=0xF456F3)
279282
280283
===============
281284
Bar Plot

docs/scatter_circle_radius.jpg

125 KB
Loading

docs/scatter_pointers.jpg

107 KB
Loading

examples/scatter_circle_radius.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Jose D. Montoya
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
from random import choice
6+
import board
7+
from ulab import numpy as np
8+
from circuitpython_uplot.plot import Plot
9+
from circuitpython_uplot.scatter import Scatter
10+
11+
12+
# Setting up the display
13+
display = board.DISPLAY
14+
15+
# Adding the plot area
16+
plot = Plot(0, 0, display.width, display.height, padding=1)
17+
plot.tick_params(tickx_height=12, ticky_height=12, tickcolor=0x939597, tickgrid=True)
18+
19+
display.show(plot)
20+
21+
a = np.linspace(1, 200, 150)
22+
z = [4, 5, 6, 7, 8]
23+
radi = [choice(z) for _ in a]
24+
b = [choice(a) for _ in a]
25+
Scatter(
26+
plot, a, b, rangex=[0, 210], rangey=[0, 210], radius=radi, pointer_color=0xF456F3
27+
)

examples/scatter_pointers.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Jose D. Montoya
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import displayio
6+
from random import choice
7+
import board
8+
from ulab import numpy as np
9+
from circuitpython_uplot.plot import Plot
10+
from circuitpython_uplot.scatter import Scatter
11+
12+
13+
# Setting up the display
14+
display = board.DISPLAY
15+
16+
# Adding the plot area
17+
plot = Plot(0, 0, display.width // 2, display.height // 2, padding=1)
18+
plot.tick_params(tickx_height=12, ticky_height=12, tickcolor=0xFF0008, tickgrid=True)
19+
plot2 = Plot(240, 0, display.width // 2, display.height // 2, padding=1)
20+
plot2.tick_params(tickx_height=6, ticky_height=6, tickcolor=0x939597, tickgrid=True)
21+
plot3 = Plot(0, 160, display.width // 2, display.height // 2, padding=1)
22+
plot3.tick_params(tickx_height=6, ticky_height=6, tickcolor=0x939597, tickgrid=False)
23+
plot4 = Plot(240, 160, display.width // 2, display.height // 2, padding=1)
24+
g = displayio.Group()
25+
g.append(plot)
26+
g.append(plot2)
27+
g.append(plot3)
28+
g.append(plot4)
29+
display.show(g)
30+
# Setting up tick parameters
31+
32+
33+
a = np.linspace(1, 100)
34+
b = [choice(a) for _ in a]
35+
Scatter(plot, a, b)
36+
Scatter(plot2, a, b, pointer="triangle", pointer_color=0x00FF00)
37+
Scatter(plot3, a, b, pointer="square", pointer_color=0xFFFFFF)
38+
Scatter(plot4, a, b, pointer="diamond", pointer_color=0xFF32FF)

0 commit comments

Comments
 (0)