Skip to content

Commit ff830e1

Browse files
committed
adding barplot update values function
1 parent b66eb12 commit ff830e1

File tree

6 files changed

+154
-9
lines changed

6 files changed

+154
-9
lines changed

.pylintrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ max-attributes=11
370370
max-bool-expr=5
371371

372372
# Maximum number of branch for function / method body
373-
max-branches=12
373+
max-branches=18
374374

375375
# Maximum number of locals for function / method body
376376
max-locals=15
@@ -385,7 +385,7 @@ max-public-methods=20
385385
max-returns=6
386386

387387
# Maximum number of statements in function / method body
388-
max-statements=60
388+
max-statements=80
389389

390390
# Minimum number of public methods for a class (see R0903).
391391
min-public-methods=1

circuitpython_uplot/ubar.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def __init__(
4545
xstart=50,
4646
projection=False,
4747
color_palette=None,
48+
max_value=None,
4849
) -> None:
4950
"""
5051
:param Uplot plot: Plot object for the scatter to be drawn
@@ -58,18 +59,32 @@ def __init__(
5859
:param list color_palette: list of colors to be used for the bars. Defaults to None.
5960
Be aware that you need to include the same number if colors as your data.
6061
This functionality will only work with filled bars.
62+
:param int max_value: for filled unprojected bars will setup the maxium value for the bars.
63+
This allows the user to update the bars in real-time. There is an example in the examples
64+
folder showing this functionality
6165
6266
"""
67+
self._bars = []
68+
self._plot_obj = plot
69+
self._projection = projection
70+
self._filled = fill
71+
72+
if max_value is None:
73+
y_max = max(y)
74+
else:
75+
y_max = max_value
76+
6377
y = [i * plot.scale for i in y]
6478
self._bar_space = int(bar_space / plot.scale)
6579
self._graphx = plot.scale * int(
6680
abs(plot._newxmax - plot._newxmin) / (len(x) + 4)
6781
)
6882
self._graphy = plot.scale * int(
69-
abs(plot._newymax - plot._newymin) / (max(y) + 2)
83+
abs(plot._newymax - plot._newymin) / (y_max + 2)
7084
)
71-
self._new_min = int(plot.transform(0, max(y), max(y), 0, 0))
72-
self._new_max = int(plot.transform(0, max(y), max(y), 0, max(y)))
85+
86+
self._new_min = int(plot.transform(0, y_max, y_max, 0, 0))
87+
self._new_max = int(plot.transform(0, y_max, y_max, 0, y_max))
7388

7489
if color_palette is not None:
7590
if projection:
@@ -86,11 +101,14 @@ def __init__(
86101
self._color_palette[self._color_index] = color
87102

88103
if plot._index_colorused >= 14:
89-
plot._index_colorused = 0
104+
plot._index_colorused = 2
105+
self._color_index = 2
106+
if color_palette:
107+
self._color_index = 0
90108

91109
if fill:
92110
for i, _ in enumerate(x):
93-
plot.append(
111+
self._bars.append(
94112
Rectangle(
95113
pixel_shader=self._color_palette,
96114
width=self._graphx,
@@ -100,6 +118,8 @@ def __init__(
100118
color_index=self._color_index,
101119
)
102120
)
121+
plot.append(self._bars[i])
122+
103123
if projection:
104124
delta = 20
105125
rx = int(delta * math.cos(-0.5))
@@ -206,6 +226,25 @@ def _draw_rectangle(
206226
draw_line(plot._plotbitmap, x + width, y, x + width, y - height, color)
207227
draw_line(plot._plotbitmap, x + width, y - height, x, y - height, color)
208228

229+
def update_values(self, values: list = None):
230+
"""
231+
Update Values of the bars
232+
"""
233+
if self._projection:
234+
raise AttributeError("Library is not designed to update projected Bars")
235+
if not self._filled:
236+
raise AttributeError("Library is not designed to update shell Bars")
237+
if values is None:
238+
raise ValueError("You must provide a list of values")
239+
for i, element in enumerate(self._bars):
240+
height = self._graphy * values[i]
241+
y = int(
242+
self._plot_obj._newymin
243+
- self._graphy * values[i] / self._plot_obj.scale
244+
)
245+
element.height = height
246+
element.y = y
247+
209248

210249
def color_fader(source_color=None, brightness=1.0, gamma=1.0):
211250
"""

circuitpython_uplot/uplot.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def __init__(
131131
if show_box:
132132
self._drawbox()
133133

134-
self._plot_palette = displayio.Palette(17)
134+
self._plot_palette = displayio.Palette(20)
135135
self._plot_palette[0] = background_color
136136
self._plot_palette[1] = box_color
137137
self._plot_palette[2] = self._tickcolor
@@ -145,7 +145,14 @@ def __init__(
145145
self._plot_palette[10] = 0x64A813
146146
self._plot_palette[11] = 0x0F4E12
147147
self._plot_palette[12] = 0xF0075E
148-
self._plot_palette[13] = 0x1AF0FF
148+
self._plot_palette[13] = 0x123456
149+
self._plot_palette[14] = 0xFF00FF
150+
self._plot_palette[15] = 0xFF0000
151+
self._plot_palette[16] = 0x440044
152+
self._plot_palette[17] = 0x2222FF
153+
self._plot_palette[18] = 0x1A50FF
154+
self._plot_palette[19] = 0xF0FF32
155+
149156
self.append(
150157
displayio.TileGrid(
151158
self._plotbitmap, pixel_shader=self._plot_palette, x=0, y=0

docs/examples.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ Bar plot example showing how to pass a user color Palette
9393
.. image:: ../docs/bar_palette.jpg
9494

9595

96+
Bar plot updating values Example
97+
---------------------------------
98+
99+
Bar Plot example showing how to update values for a filled bars bar plot
100+
101+
.. literalinclude:: ../examples/uplot_ubar_updating_values.py
102+
:caption: examples/uplot_ubar_updating_values.py
103+
:lines: 5-
104+
105+
96106
Ubar 3D Example
97107
----------------
98108

docs/quick_start.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,31 @@ appearance
344344
ubar(plot, a, b, color=0xFF1000, fill=True, bar_space=30, xstart=70, projection=True)
345345
346346
347+
For filled unprojected bar you can update their values. This is useful for data logging.
348+
the max_value argument will allow you to set the maximum value of the graph. The plot will scale
349+
according to this max value, and bar plot will update their values accordingly
350+
351+
.. code-block:: python
352+
353+
import board
354+
from circuitpython_uplot.uplot import Uplot
355+
from circuitpython_uplot.ubar import ubar
356+
357+
display = board.DISPLAY
358+
plot = Uplot(0, 0, display.width, display.height)
359+
360+
361+
a = ["a", "b", "c", "d"]
362+
b = [3, 5, 1, 7]
363+
my_ubar = ubar(plot, a, b, color=0xFF1000, fill=True, color_palette=[0xFF1000, 0x00FF00, 0xFFFF00, 0x123456], max_value=10)
364+
365+
366+
Then you can update the values of the bar plot:
367+
368+
.. code-block:: python
369+
370+
my_ubar.update_values([1, 2, 3, 4])
371+
347372
===============
348373
Fillbetween
349374
===============
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Jose D. Montoya
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import board
6+
from circuitpython_uplot.uplot import Uplot, color
7+
from circuitpython_uplot.ubar import ubar
8+
import time
9+
10+
# Setting up the display
11+
display = board.DISPLAY
12+
13+
# Configuring display dimensions
14+
DISPLAY_WIDTH = 480
15+
DISPLAY_HEIGHT = 320
16+
17+
# Defining the plot
18+
plot = Uplot(
19+
0,
20+
0,
21+
DISPLAY_WIDTH,
22+
DISPLAY_HEIGHT,
23+
background_color=color.BLACK,
24+
padding=10,
25+
box_color=color.BLACK,
26+
)
27+
28+
# Dummy data to plot
29+
some_values = [55, 20, 25, 30, 35, 10]
30+
a = ["a", "b", "c", "d", "e", "f"]
31+
32+
add = 1
33+
# Showing the plot
34+
display.show(plot)
35+
36+
# Creating the bar
37+
my_ubar = ubar(
38+
plot,
39+
a,
40+
some_values,
41+
0xFF1000,
42+
True,
43+
color_palette=[
44+
0xFF1000,
45+
0x00FF00,
46+
0x0000FF,
47+
0xFFFF00,
48+
0x00FFFF,
49+
0x123456,
50+
],
51+
max_value=100,
52+
)
53+
54+
for i in range(20):
55+
values_changed = [j + add for j in some_values]
56+
my_ubar.update_values(values_changed)
57+
add += 1
58+
time.sleep(0.1)
59+
60+
for i in range(20):
61+
values_changed = [j + add for j in some_values]
62+
my_ubar.update_values(values_changed)
63+
add -= 1
64+
time.sleep(0.1)

0 commit comments

Comments
 (0)