From 6e181dfadcfb61c5e398037235cbb1a320053bf5 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Sun, 7 Jun 2020 10:03:34 -0500 Subject: [PATCH 01/17] Add example using line for a moving sparkline graph --- examples/display_shapes_sparkline.py | 338 +++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 examples/display_shapes_sparkline.py diff --git a/examples/display_shapes_sparkline.py b/examples/display_shapes_sparkline.py new file mode 100644 index 0000000..81944c6 --- /dev/null +++ b/examples/display_shapes_sparkline.py @@ -0,0 +1,338 @@ +# class of sparklines in CircuitPython +# created by Kevin Matocha - Copyright 2020 (C) + +# See the bottom for a code example using the `sparkline` Class. + +# # File: display_shapes_sparkline.py +# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# +# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# or adding to a `displayio.Group` to be displayed. +# +# When creating the sparkline, identify the number of `max_items` that will be included in the graph. +# When additional elements are added to the sparkline and the number of items has exceeded max_items, +# any excess values are removed from the left of the graph, and new values are added to the right. + +import displayio + + +class sparkline(displayio.Group): + def __init__( + self, + width, + height, + max_items, + yMin=None, # None = autoscaling + yMax=None, # None = autoscaling + line_color=0xFFFFFF, # default = WHITE + x=0, + y=0, + ): + + # define class instance variables + self.width = width # in pixels + self.height = height # in pixels + self.line_color = line_color # + self._max_items = max_items # maximum number of items in the list + self._spark_list = [] # list containing the values + self.yMin = yMin # minimum of y-axis (None: autoscale) + self.yMax = yMax # maximum of y-axis (None: autoscale) + self._x = x + self._y = y + + super().__init__( + max_size=self._max_items - 1, x=x, y=y + ) # self is a group of lines + + def add_value(self, value): + if value is not None: + if ( + len(self._spark_list) >= self._max_items + ): # if list is full, remove the first item + self._spark_list.pop(0) + self._spark_list.append(value) + # self.update() + + @staticmethod + def _xintercept( + x1, y1, x2, y2, horizontalY + ): # finds intercept of the line and a horizontal line at horizontalY + slope = (y2 - y1) / (x2 - x1) + b = y1 - slope * x1 + + if slope == 0 and y1 != horizontalY: # does not intercept horizontalY + return None + else: + xint = ( + horizontalY - b + ) / slope # calculate the x-intercept at position y=horizontalY + return int(xint) + + def _plotLine(self, x1, last_value, x2, value, yBottom, yTop): + + from adafruit_display_shapes.line import Line + + y2 = int(self.height * (yTop - value) / (yTop - yBottom)) + y1 = int(self.height * (yTop - last_value) / (yTop - yBottom)) + self.append(Line(x1, y1, x2, y2, self.line_color)) # plot the line + + def update(self): + # What to do if there is 0 or 1 element? + + # get the y range + if self.yMin == None: + yBottom = min(self._spark_list) + else: + yBottom = self.yMin + + if self.yMax == None: + yTop = max(self._spark_list) + else: + yTop = self.yMax + + if len(self._spark_list) > 2: + xpitch = self.width / ( + len(self._spark_list) - 1 + ) # this is a float, only make int when plotting the line + + for i in range(len(self)): # remove all items from the current group + self.pop() + + for count, value in enumerate(self._spark_list): + if count == 0: + pass # don't draw anything for a first point + else: + x2 = int(xpitch * count) + x1 = int(xpitch * (count - 1)) + + # print("x1: {}, x2: {}".format(x1,x2)) + + if (yBottom <= last_value <= yTop) and ( + yBottom <= value <= yTop + ): # both points are in range, plot the line + self._plotLine(x1, last_value, x2, value, yBottom, yTop) + + else: # at least one point is out of range, clip one or both ends the line + if ((last_value > yTop) and (value > yTop)) or ( + (last_value < yBottom) and (value < yBottom) + ): + # both points are on the same side out of range: don't draw anything + pass + else: + xintBottom = self._xintercept( + x1, last_value, x2, value, yBottom + ) # get possible new x intercept points + xintTop = self._xintercept( + x1, last_value, x2, value, yTop + ) # on the top and bottom of range + + if (xintBottom is None) or ( + xintTop is None + ): # out of range doublecheck + pass + else: + # Initialize the adjusted values as the baseline + adj_x1 = x1 + adj_last_value = last_value + adj_x2 = x2 + adj_value = value + + if value > last_value: # slope is positive + if xintBottom >= x1: # bottom is clipped + adj_x1 = xintBottom + adj_last_value = yBottom # y1 + if xintTop <= x2: # top is clipped + adj_x2 = xintTop + adj_value = yTop # y2 + else: # slope is negative + if xintTop >= x1: # top is clipped + adj_x1 = xintTop + adj_last_value = yTop # y1 + if xintBottom <= x2: # bottom is clipped + adj_x2 = xintBottom + adj_value = yBottom # y2 + + self._plotLine( + adj_x1, + adj_last_value, + adj_x2, + adj_value, + yBottom, + yTop, + ) + + last_value = value # store value for the next iteration + + def values(self): + return self._spark_list + + +# The following is an example that shows the + +# setup display +# instance sparklines +# add to the display +# Loop the following steps: +# add new values to sparkline `add_value` +# update the sparklines `update` + +import board +import displayio +import random +import time +from adafruit_ili9341 import ILI9341 + +# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class + + +# Setup the LCD display + +displayio.release_displays() + + +# setup the SPI bus +spi = board.SPI() +tft_cs = board.D9 # arbitrary, pin not used +tft_dc = board.D10 +tft_backlight = board.D12 +tft_reset = board.D11 + +while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass +spi.unlock() + +display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, +) + +print("spi.frequency: {}".format(spi.frequency)) + +# Number of pixels in the display +DISPLAY_WIDTH = 320 +DISPLAY_HEIGHT = 240 + +# create the display +display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, + auto_refresh=True, + native_frames_per_second=90, +) + +# reset the display to show nothing. +display.show(None) + +########################################## +# Create background bitmaps and sparklines +########################################## + +# Baseline size of the sparkline chart, in pixels. +chartWidth = 50 +chartHeight = 50 + +# Setup the first bitmap and sparkline +palette = displayio.Palette(1) # color palette used for bitmap (one color) +palette[0] = 0x444411 + +bitmap = displayio.Bitmap(chartWidth, chartHeight, 1) # create a bitmap +tileGrid = displayio.TileGrid( + bitmap, pixel_shader=palette, x=10, y=10 +) # Add the bitmap to tilegrid +mySparkline = sparkline( + width=chartWidth, height=chartHeight, max_items=40, yMin=-1, yMax=1.25, x=10, y=10 +) +# mySparkline uses a vertical y range between -1 to +1.25 and will contain a maximum of 40 items + +# Setup the second bitmap and sparkline +palette2 = displayio.Palette(1) # color palette used for bitmap2 (one color) +palette2[0] = 0x0000FF + +bitmap2 = displayio.Bitmap(chartWidth * 2, chartHeight * 2, 1) # create bitmap2 +tileGrid2 = displayio.TileGrid( + bitmap2, pixel_shader=palette2, x=150, y=10 +) # Add bitmap2 to tilegrid2 +mySparkline2 = sparkline( + width=chartWidth * 2, + height=chartHeight * 2, + max_items=10, + yMin=0, + yMax=1, + x=150, + y=10, + line_color=0xFF00FF, +) +# mySparkline2 uses a vertical y range between 0 to 1, and will contain a maximum of 10 items + +# Setup the third bitmap and sparkline +palette3 = displayio.Palette(1) # color palette used for bitmap (one color) +palette3[0] = 0x11FF44 +bitmap3 = displayio.Bitmap(DISPLAY_WIDTH, chartHeight * 2, 1) # create bitmap3 +tileGrid3 = displayio.TileGrid( + bitmap3, pixel_shader=palette3, x=0, y=120 +) # Add bitmap3 to tilegrid3 +mySparkline3 = sparkline( + width=DISPLAY_WIDTH, + height=chartHeight * 2, + max_items=20, + x=0, + y=120, + line_color=0xFFFFFF, +) +# mySparkline3 will contain a maximum of 20 items +# since yMin and yMax are not specified, mySparkline3 uses autoranging for both the top and bottom ranges. +# Note: Any unspecified edge limit (yMin, yMax) will autorange that edge based on the data in the list. + + +# Create a group to hold the three bitmap TileGrids and the three sparklines and +# append them into the group (myGroup) +# +# Note: In cases where display elements will overlap, then the order the elements are added to the +# group will set which is on top. Latter elements are displayed on top of former elemtns. +myGroup = displayio.Group(max_size=8) +myGroup.append(tileGrid) +myGroup.append(mySparkline) + +myGroup.append(tileGrid2) +myGroup.append(mySparkline2) + +myGroup.append(tileGrid3) +myGroup.append(mySparkline3) + + +# Display myGroup that contains all the bitmap TileGrids and sparklines +display.show(myGroup) + +# Start the main loop +while True: + + # add a new random value to each sparkline + mySparkline.add_value(random.uniform(0, 1)) + + mySparkline2.add_value(random.uniform(-1, 2)) + # Note: For mySparline2, the random value will sometimes + # be out of the y-range to exercise the top and bottom clipping + + mySparkline3.add_value(random.uniform(0, 1)) + + # Turn off the display refresh while updating the sparklines + display.auto_refresh = False + + # Update the drawings for all three sparklines + mySparkline.update() + mySparkline2.update() + mySparkline3.update() + + # Turn on the display refreshing + display.auto_refresh = True + + # The display seems to be less jittery if a small sleep time is provided + time.sleep(0.1) From 46bceae26e8918a9a0039195226cfa8ede00ac63 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Mon, 20 Jul 2020 19:02:19 -0500 Subject: [PATCH 02/17] Separated class file, updated examples --- adafruit_display_shapes/sparkline.py | 170 +++++++++ examples/display_shapes_sparkline.py | 338 ------------------ .../display_shapes_sparkline_simpletest.py | 128 +++++++ examples/display_shapes_sparkline_ticks.py | 197 ++++++++++ examples/display_shapes_sparkline_triple.py | 263 ++++++++++++++ 5 files changed, 758 insertions(+), 338 deletions(-) create mode 100644 adafruit_display_shapes/sparkline.py delete mode 100644 examples/display_shapes_sparkline.py create mode 100755 examples/display_shapes_sparkline_simpletest.py create mode 100755 examples/display_shapes_sparkline_ticks.py create mode 100755 examples/display_shapes_sparkline_triple.py diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py new file mode 100644 index 0000000..125facc --- /dev/null +++ b/adafruit_display_shapes/sparkline.py @@ -0,0 +1,170 @@ +# class of sparklines in CircuitPython +# created by Kevin Matocha - Copyright 2020 (C) + +# See the bottom for a code example using the `sparkline` Class. + +# # File: display_shapes_sparkline.py +# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# +# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# or adding to a `displayio.Group` to be displayed. +# +# When creating the sparkline, identify the number of `max_items` that will be included in the graph. +# When additional elements are added to the sparkline and the number of items has exceeded max_items, +# any excess values are removed from the left of the graph, and new values are added to the right. + +import displayio +from adafruit_display_shapes.line import Line + + +class Sparkline(displayio.Group): + def __init__( + self, + width, + height, + max_items, + yMin=None, # None = autoscaling + yMax=None, # None = autoscaling + x=0, + y=0, + color=0xFFFFFF, # line color, default is WHITE + ): + + # define class instance variables + self.width = width # in pixels + self.height = height # in pixels + self.color = color # + self._max_items = max_items # maximum number of items in the list + self._spark_list = [] # list containing the values + self.yMin = yMin # minimum of y-axis (None: autoscale) + self.yMax = yMax # maximum of y-axis (None: autoscale) + self.yBottom = yMin # yBottom: The actual minimum value of the vertical scale, will be updated if autorange + self.yTop = yMax # yTop: The actual minimum value of the vertical scale, will be updated if autorange + self._x = x + self._y = y + + super().__init__( + max_size=self._max_items - 1, x=x, y=y + ) # self is a group of lines + + def add_value(self, value): + if value is not None: + if ( + len(self._spark_list) >= self._max_items + ): # if list is full, remove the first item + self._spark_list.pop(0) + self._spark_list.append(value) + # self.update() + + @staticmethod + def _xintercept( + x1, y1, x2, y2, horizontalY + ): # finds intercept of the line and a horizontal line at horizontalY + slope = (y2 - y1) / (x2 - x1) + b = y1 - slope * x1 + + if slope == 0 and y1 != horizontalY: # does not intercept horizontalY + return None + else: + xint = ( + horizontalY - b + ) / slope # calculate the x-intercept at position y=horizontalY + return int(xint) + + def _plotLine(self, x1, last_value, x2, value, yBottom, yTop): + + y2 = int(self.height * (yTop - value) / (yTop - yBottom)) + y1 = int(self.height * (yTop - last_value) / (yTop - yBottom)) + self.append(Line(x1, y1, x2, y2, self.color)) # plot the line + + def update(self): + # What to do if there is 0 or 1 element? + + # get the y range + if self.yMin == None: + self.yBottom = min(self._spark_list) + else: + self.yBottom = self.yMin + + if self.yMax == None: + self.yTop = max(self._spark_list) + else: + self.yTop = self.yMax + + if len(self._spark_list) > 2: + xpitch = self.width / ( + len(self._spark_list) - 1 + ) # this is a float, only make int when plotting the line + + for i in range(len(self)): # remove all items from the current group + self.pop() + + for count, value in enumerate(self._spark_list): + if count == 0: + pass # don't draw anything for a first point + else: + x2 = int(xpitch * count) + x1 = int(xpitch * (count - 1)) + + # print("x1: {}, x2: {}".format(x1,x2)) + + if (self.yBottom <= last_value <= self.yTop) and ( + self.yBottom <= value <= self.yTop + ): # both points are in range, plot the line + self._plotLine( + x1, last_value, x2, value, self.yBottom, self.yTop + ) + + else: # at least one point is out of range, clip one or both ends the line + if ((last_value > self.yTop) and (value > self.yTop)) or ( + (last_value < self.yBottom) and (value < self.yBottom) + ): + # both points are on the same side out of range: don't draw anything + pass + else: + xintBottom = self._xintercept( + x1, last_value, x2, value, self.yBottom + ) # get possible new x intercept points + xintTop = self._xintercept( + x1, last_value, x2, value, self.yTop + ) # on the top and bottom of range + + if (xintBottom is None) or ( + xintTop is None + ): # out of range doublecheck + pass + else: + # Initialize the adjusted values as the baseline + adj_x1 = x1 + adj_last_value = last_value + adj_x2 = x2 + adj_value = value + + if value > last_value: # slope is positive + if xintBottom >= x1: # bottom is clipped + adj_x1 = xintBottom + adj_last_value = self.yBottom # y1 + if xintTop <= x2: # top is clipped + adj_x2 = xintTop + adj_value = self.yTop # y2 + else: # slope is negative + if xintTop >= x1: # top is clipped + adj_x1 = xintTop + adj_last_value = self.yTop # y1 + if xintBottom <= x2: # bottom is clipped + adj_x2 = xintBottom + adj_value = self.yBottom # y2 + + self._plotLine( + adj_x1, + adj_last_value, + adj_x2, + adj_value, + self.yBottom, + self.yTop, + ) + + last_value = value # store value for the next iteration + + def values(self): + return self._spark_list diff --git a/examples/display_shapes_sparkline.py b/examples/display_shapes_sparkline.py deleted file mode 100644 index 81944c6..0000000 --- a/examples/display_shapes_sparkline.py +++ /dev/null @@ -1,338 +0,0 @@ -# class of sparklines in CircuitPython -# created by Kevin Matocha - Copyright 2020 (C) - -# See the bottom for a code example using the `sparkline` Class. - -# # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. -# -# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` -# or adding to a `displayio.Group` to be displayed. -# -# When creating the sparkline, identify the number of `max_items` that will be included in the graph. -# When additional elements are added to the sparkline and the number of items has exceeded max_items, -# any excess values are removed from the left of the graph, and new values are added to the right. - -import displayio - - -class sparkline(displayio.Group): - def __init__( - self, - width, - height, - max_items, - yMin=None, # None = autoscaling - yMax=None, # None = autoscaling - line_color=0xFFFFFF, # default = WHITE - x=0, - y=0, - ): - - # define class instance variables - self.width = width # in pixels - self.height = height # in pixels - self.line_color = line_color # - self._max_items = max_items # maximum number of items in the list - self._spark_list = [] # list containing the values - self.yMin = yMin # minimum of y-axis (None: autoscale) - self.yMax = yMax # maximum of y-axis (None: autoscale) - self._x = x - self._y = y - - super().__init__( - max_size=self._max_items - 1, x=x, y=y - ) # self is a group of lines - - def add_value(self, value): - if value is not None: - if ( - len(self._spark_list) >= self._max_items - ): # if list is full, remove the first item - self._spark_list.pop(0) - self._spark_list.append(value) - # self.update() - - @staticmethod - def _xintercept( - x1, y1, x2, y2, horizontalY - ): # finds intercept of the line and a horizontal line at horizontalY - slope = (y2 - y1) / (x2 - x1) - b = y1 - slope * x1 - - if slope == 0 and y1 != horizontalY: # does not intercept horizontalY - return None - else: - xint = ( - horizontalY - b - ) / slope # calculate the x-intercept at position y=horizontalY - return int(xint) - - def _plotLine(self, x1, last_value, x2, value, yBottom, yTop): - - from adafruit_display_shapes.line import Line - - y2 = int(self.height * (yTop - value) / (yTop - yBottom)) - y1 = int(self.height * (yTop - last_value) / (yTop - yBottom)) - self.append(Line(x1, y1, x2, y2, self.line_color)) # plot the line - - def update(self): - # What to do if there is 0 or 1 element? - - # get the y range - if self.yMin == None: - yBottom = min(self._spark_list) - else: - yBottom = self.yMin - - if self.yMax == None: - yTop = max(self._spark_list) - else: - yTop = self.yMax - - if len(self._spark_list) > 2: - xpitch = self.width / ( - len(self._spark_list) - 1 - ) # this is a float, only make int when plotting the line - - for i in range(len(self)): # remove all items from the current group - self.pop() - - for count, value in enumerate(self._spark_list): - if count == 0: - pass # don't draw anything for a first point - else: - x2 = int(xpitch * count) - x1 = int(xpitch * (count - 1)) - - # print("x1: {}, x2: {}".format(x1,x2)) - - if (yBottom <= last_value <= yTop) and ( - yBottom <= value <= yTop - ): # both points are in range, plot the line - self._plotLine(x1, last_value, x2, value, yBottom, yTop) - - else: # at least one point is out of range, clip one or both ends the line - if ((last_value > yTop) and (value > yTop)) or ( - (last_value < yBottom) and (value < yBottom) - ): - # both points are on the same side out of range: don't draw anything - pass - else: - xintBottom = self._xintercept( - x1, last_value, x2, value, yBottom - ) # get possible new x intercept points - xintTop = self._xintercept( - x1, last_value, x2, value, yTop - ) # on the top and bottom of range - - if (xintBottom is None) or ( - xintTop is None - ): # out of range doublecheck - pass - else: - # Initialize the adjusted values as the baseline - adj_x1 = x1 - adj_last_value = last_value - adj_x2 = x2 - adj_value = value - - if value > last_value: # slope is positive - if xintBottom >= x1: # bottom is clipped - adj_x1 = xintBottom - adj_last_value = yBottom # y1 - if xintTop <= x2: # top is clipped - adj_x2 = xintTop - adj_value = yTop # y2 - else: # slope is negative - if xintTop >= x1: # top is clipped - adj_x1 = xintTop - adj_last_value = yTop # y1 - if xintBottom <= x2: # bottom is clipped - adj_x2 = xintBottom - adj_value = yBottom # y2 - - self._plotLine( - adj_x1, - adj_last_value, - adj_x2, - adj_value, - yBottom, - yTop, - ) - - last_value = value # store value for the next iteration - - def values(self): - return self._spark_list - - -# The following is an example that shows the - -# setup display -# instance sparklines -# add to the display -# Loop the following steps: -# add new values to sparkline `add_value` -# update the sparklines `update` - -import board -import displayio -import random -import time -from adafruit_ili9341 import ILI9341 - -# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class - - -# Setup the LCD display - -displayio.release_displays() - - -# setup the SPI bus -spi = board.SPI() -tft_cs = board.D9 # arbitrary, pin not used -tft_dc = board.D10 -tft_backlight = board.D12 -tft_reset = board.D11 - -while not spi.try_lock(): - spi.configure(baudrate=32000000) - pass -spi.unlock() - -display_bus = displayio.FourWire( - spi, - command=tft_dc, - chip_select=tft_cs, - reset=tft_reset, - baudrate=32000000, - polarity=1, - phase=1, -) - -print("spi.frequency: {}".format(spi.frequency)) - -# Number of pixels in the display -DISPLAY_WIDTH = 320 -DISPLAY_HEIGHT = 240 - -# create the display -display = ILI9341( - display_bus, - width=DISPLAY_WIDTH, - height=DISPLAY_HEIGHT, - rotation=180, - auto_refresh=True, - native_frames_per_second=90, -) - -# reset the display to show nothing. -display.show(None) - -########################################## -# Create background bitmaps and sparklines -########################################## - -# Baseline size of the sparkline chart, in pixels. -chartWidth = 50 -chartHeight = 50 - -# Setup the first bitmap and sparkline -palette = displayio.Palette(1) # color palette used for bitmap (one color) -palette[0] = 0x444411 - -bitmap = displayio.Bitmap(chartWidth, chartHeight, 1) # create a bitmap -tileGrid = displayio.TileGrid( - bitmap, pixel_shader=palette, x=10, y=10 -) # Add the bitmap to tilegrid -mySparkline = sparkline( - width=chartWidth, height=chartHeight, max_items=40, yMin=-1, yMax=1.25, x=10, y=10 -) -# mySparkline uses a vertical y range between -1 to +1.25 and will contain a maximum of 40 items - -# Setup the second bitmap and sparkline -palette2 = displayio.Palette(1) # color palette used for bitmap2 (one color) -palette2[0] = 0x0000FF - -bitmap2 = displayio.Bitmap(chartWidth * 2, chartHeight * 2, 1) # create bitmap2 -tileGrid2 = displayio.TileGrid( - bitmap2, pixel_shader=palette2, x=150, y=10 -) # Add bitmap2 to tilegrid2 -mySparkline2 = sparkline( - width=chartWidth * 2, - height=chartHeight * 2, - max_items=10, - yMin=0, - yMax=1, - x=150, - y=10, - line_color=0xFF00FF, -) -# mySparkline2 uses a vertical y range between 0 to 1, and will contain a maximum of 10 items - -# Setup the third bitmap and sparkline -palette3 = displayio.Palette(1) # color palette used for bitmap (one color) -palette3[0] = 0x11FF44 -bitmap3 = displayio.Bitmap(DISPLAY_WIDTH, chartHeight * 2, 1) # create bitmap3 -tileGrid3 = displayio.TileGrid( - bitmap3, pixel_shader=palette3, x=0, y=120 -) # Add bitmap3 to tilegrid3 -mySparkline3 = sparkline( - width=DISPLAY_WIDTH, - height=chartHeight * 2, - max_items=20, - x=0, - y=120, - line_color=0xFFFFFF, -) -# mySparkline3 will contain a maximum of 20 items -# since yMin and yMax are not specified, mySparkline3 uses autoranging for both the top and bottom ranges. -# Note: Any unspecified edge limit (yMin, yMax) will autorange that edge based on the data in the list. - - -# Create a group to hold the three bitmap TileGrids and the three sparklines and -# append them into the group (myGroup) -# -# Note: In cases where display elements will overlap, then the order the elements are added to the -# group will set which is on top. Latter elements are displayed on top of former elemtns. -myGroup = displayio.Group(max_size=8) -myGroup.append(tileGrid) -myGroup.append(mySparkline) - -myGroup.append(tileGrid2) -myGroup.append(mySparkline2) - -myGroup.append(tileGrid3) -myGroup.append(mySparkline3) - - -# Display myGroup that contains all the bitmap TileGrids and sparklines -display.show(myGroup) - -# Start the main loop -while True: - - # add a new random value to each sparkline - mySparkline.add_value(random.uniform(0, 1)) - - mySparkline2.add_value(random.uniform(-1, 2)) - # Note: For mySparline2, the random value will sometimes - # be out of the y-range to exercise the top and bottom clipping - - mySparkline3.add_value(random.uniform(0, 1)) - - # Turn off the display refresh while updating the sparklines - display.auto_refresh = False - - # Update the drawings for all three sparklines - mySparkline.update() - mySparkline2.update() - mySparkline3.update() - - # Turn on the display refreshing - display.auto_refresh = True - - # The display seems to be less jittery if a small sleep time is provided - time.sleep(0.1) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py new file mode 100755 index 0000000..46c2c5e --- /dev/null +++ b/examples/display_shapes_sparkline_simpletest.py @@ -0,0 +1,128 @@ +# class of sparklines in CircuitPython +# created by Kevin Matocha - Copyright 2020 (C) + +# See the bottom for a code example using the `sparkline` Class. + +# # File: display_shapes_sparkline.py +# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# +# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# or adding to a `displayio.Group` to be displayed. +# +# When creating the sparkline, identify the number of `max_items` that will be included in the graph. +# When additional elements are added to the sparkline and the number of items has exceeded max_items, +# any excess values are removed from the left of the graph, and new values are added to the right. + + +# The following is an example that shows the + +# setup display +# instance sparklines +# add to the display +# Loop the following steps: +# add new values to sparkline `add_value` +# update the sparklines `update` + +import board +import displayio +import terminalio +import random +import time +from adafruit_display_shapes.sparkline import Sparkline +from adafruit_ili9341 import ILI9341 +from adafruit_display_text import label + +import gc + +# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class + + +# Setup the LCD display + +displayio.release_displays() + + +# setup the SPI bus +spi = board.SPI() +tft_cs = board.D9 # arbitrary, pin not used +tft_dc = board.D10 +tft_backlight = board.D12 +tft_reset = board.D11 + +while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass +spi.unlock() + +display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, +) + +print("spi.frequency: {}".format(spi.frequency)) + +# Number of pixels in the display +DISPLAY_WIDTH = 320 +DISPLAY_HEIGHT = 240 + +# create the display +display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, + auto_refresh=True, + native_frames_per_second=90, +) + +# reset the display to show nothing. +display.show(None) + +########################################## +# Create background bitmaps and sparklines +########################################## + +# Baseline size of the sparkline chart, in pixels. +chartWidth = DISPLAY_WIDTH +chartHeight = DISPLAY_HEIGHT + + +# mySparkline1 uses a vertical y range between 0 to 10 and will contain a maximum of 40 items +mySparkline1 = Sparkline( + width=chartWidth, height=chartHeight, max_items=40, yMin=0, yMax=10, x=0, y=0 +) + + +# Create a group to hold the sparkline and append the sparkline into the group (myGroup) +# +# Note: In cases where display elements will overlap, then the order the elements are added to the +# group will set which is on top. Latter elements are displayed on top of former elemtns. +myGroup = displayio.Group(max_size=1) + +myGroup.append(mySparkline1) + + +# Display myGroup that contains the sparkline +display.show(myGroup) + + +# Start the main loop +while True: + + # add_value: add a new value to a sparkline + # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random + # values (between 0 and 10) will fit within the visible range of this sparkline + mySparkline1.add_value(random.uniform(0, 10)) + + display.auto_refresh = False + mySparkline1.update() + display.auto_refresh = True + + # The display seems to be less jittery if a small sleep time is provided + # You can adjust this to see if it has any effect + time.sleep(0.01) diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py new file mode 100755 index 0000000..d871416 --- /dev/null +++ b/examples/display_shapes_sparkline_ticks.py @@ -0,0 +1,197 @@ +# class of sparklines in CircuitPython +# created by Kevin Matocha - Copyright 2020 (C) + +# See the bottom for a code example using the `sparkline` Class. + +# # File: display_shapes_sparkline.py +# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# +# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# or adding to a `displayio.Group` to be displayed. +# +# When creating the sparkline, identify the number of `max_items` that will be included in the graph. +# When additional elements are added to the sparkline and the number of items has exceeded max_items, +# any excess values are removed from the left of the graph, and new values are added to the right. + + +# The following is an example that shows the + +# setup display +# instance sparklines +# add to the display +# Loop the following steps: +# add new values to sparkline `add_value` +# update the sparklines `update` + +import board +import displayio +import terminalio +import random +import time +from adafruit_display_shapes.sparkline import Sparkline +from adafruit_ili9341 import ILI9341 +from adafruit_display_text import label +from adafruit_display_shapes.line import Line +from adafruit_display_shapes.rect import Rect + +import gc + +# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class + + +# Setup the LCD display + +displayio.release_displays() + + +# setup the SPI bus +spi = board.SPI() +tft_cs = board.D9 # arbitrary, pin not used +tft_dc = board.D10 +tft_backlight = board.D12 +tft_reset = board.D11 + +while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass +spi.unlock() + +display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, +) + +print("spi.frequency: {}".format(spi.frequency)) + +# Number of pixels in the display +DISPLAY_WIDTH = 320 +DISPLAY_HEIGHT = 240 + +# create the display +display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, + auto_refresh=True, + native_frames_per_second=90, +) + +# reset the display to show nothing. +display.show(None) + +########################################## +# Create background bitmaps and sparklines +########################################## + +# Baseline size of the sparkline chart, in pixels. +chartWidth = 270 +chartHeight = 180 + +font = terminalio.FONT + +lineColor = 0xFFFFFF + +# Setup the first bitmap and sparkline +# This sparkline has no background bitmap +# mySparkline1 uses a vertical y range between 0 to 10 and will contain a maximum of 40 items +mySparkline1 = Sparkline( + width=chartWidth, + height=chartHeight, + max_items=40, + yMin=0, + yMax=10, + x=40, + y=30, + color=lineColor, +) + +# Label the y-axis range + +textXOffset = -10 +textLabel1a = label.Label( + font=font, text=str(mySparkline1.yTop), color=lineColor +) # yTop label +textLabel1a.anchor_point = (1, 0.5) # set the anchorpoint at right-center +textLabel1a.anchored_position = ( + mySparkline1.x + textXOffset, + mySparkline1.y, +) # set the text anchored position to the upper right of the graph + +textLabel1b = label.Label( + font=font, text=str(mySparkline1.yBottom), color=lineColor +) # yTop label +textLabel1b.anchor_point = (1, 0.5) # set the anchorpoint at right-center +textLabel1b.anchored_position = ( + mySparkline1.x + textXOffset, + mySparkline1.y + chartHeight, +) # set the text anchored position to the upper right of the graph + + +boundingRectangle = Rect( + mySparkline1.x, mySparkline1.y, chartWidth + 1, chartHeight + 1, outline=lineColor +) + + +# Create a group to hold the sparkline, text, rectangle and tickmarks +# append them into the group (myGroup) +# +# Note: In cases where display elements will overlap, then the order the elements are added to the +# group will set which is on top. Latter elements are displayed on top of former elemtns. + +myGroup = displayio.Group(max_size=20) + +myGroup.append(mySparkline1) +myGroup.append(textLabel1a) +myGroup.append(textLabel1b) +myGroup.append(boundingRectangle) + +totalTicks = 10 + +for i in range(totalTicks + 1): + xStart = mySparkline1.x - 5 + xEnd = mySparkline1.x + yBoth = mySparkline1.y + i * int(round(chartHeight / (totalTicks))) + myGroup.append(Line(xStart, yBoth, xEnd, yBoth, color=lineColor)) +myGroup.append( + Line( + xStart, + mySparkline1.y + chartHeight, + xEnd, + mySparkline1.y + chartHeight, + color=lineColor, + ) +) + + +# Display myGroup that contains all the bitmap TileGrids and sparklines +display.show(myGroup) + + +# Start the main loop +while True: + + # add_value: add a new value to a sparkline + # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random + # values (between 0 and 10) will fit within the visible range of this sparkline + mySparkline1.add_value(random.uniform(0, 10)) + + # Turn off auto_refresh to prevent partial updates of the screen during updates + # of the sparkline drawing + display.auto_refresh = False + # Update all the sparklines + mySparkline1.update() + # Turn on auto_refresh for the display + display.auto_refresh = True + + # The display seems to be less jittery if a small sleep time is provided + # You can adjust this to see if it has any effect + time.sleep(0.01) + + # Uncomment the next line to print the amount of available memory + # print('memory free: {}'.format(gc.mem_free())) diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py new file mode 100755 index 0000000..1fdcb1a --- /dev/null +++ b/examples/display_shapes_sparkline_triple.py @@ -0,0 +1,263 @@ +# class of sparklines in CircuitPython +# created by Kevin Matocha - Copyright 2020 (C) + +# See the bottom for a code example using the `sparkline` Class. + +# # File: display_shapes_sparkline.py +# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# +# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# or adding to a `displayio.Group` to be displayed. +# +# When creating the sparkline, identify the number of `max_items` that will be included in the graph. +# When additional elements are added to the sparkline and the number of items has exceeded max_items, +# any excess values are removed from the left of the graph, and new values are added to the right. + + +# The following is an example that shows the + +# setup display +# instance sparklines +# add to the display +# Loop the following steps: +# add new values to sparkline `add_value` +# update the sparklines `update` + +import board +import displayio +import terminalio +import random +import time +from adafruit_display_shapes.sparkline import Sparkline +from adafruit_ili9341 import ILI9341 +from adafruit_display_text import label + +import gc + +# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class + + +# Setup the LCD display + +displayio.release_displays() + + +# setup the SPI bus +spi = board.SPI() +tft_cs = board.D9 # arbitrary, pin not used +tft_dc = board.D10 +tft_backlight = board.D12 +tft_reset = board.D11 + +while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass +spi.unlock() + +display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, +) + +print("spi.frequency: {}".format(spi.frequency)) + +# Number of pixels in the display +DISPLAY_WIDTH = 320 +DISPLAY_HEIGHT = 240 + +# create the display +display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, + auto_refresh=True, + native_frames_per_second=90, +) + +# reset the display to show nothing. +display.show(None) + +########################################## +# Create background bitmaps and sparklines +########################################## + +# Baseline size of the sparkline chart, in pixels. +chartWidth = 50 +chartHeight = 50 + +font = terminalio.FONT + +# Setup the first bitmap and sparkline +# This sparkline has no background bitmap +# mySparkline1 uses a vertical y range between -1 to +1.25 and will contain a maximum of 40 items +mySparkline1 = Sparkline( + width=chartWidth, height=chartHeight, max_items=40, yMin=-1, yMax=1.25, x=10, y=10 +) + +# Label the y-axis range +textLabel1a = label.Label( + font=font, text=str(mySparkline1.yTop), color=0xFFFFFF +) # yTop label +textLabel1a.anchor_point = (0, 0.5) # set the anchorpoint +textLabel1a.anchored_position = ( + 10 + chartWidth, + 10, +) # set the text anchored position to the upper right of the graph + +textLabel1b = label.Label( + font=font, text=str(mySparkline1.yBottom), color=0xFFFFFF +) # yTop label +textLabel1b.anchor_point = (0, 0.5) # set the anchorpoint +textLabel1b.anchored_position = ( + 10 + chartWidth, + 10 + chartHeight, +) # set the text anchored position to the upper right of the graph + + +# Setup the second bitmap and sparkline +# mySparkline2 uses a vertical y range between 0 to 1, and will contain a maximum of 10 items +# +palette2 = displayio.Palette(1) # color palette used for bitmap2 (one color) +palette2[0] = 0x0000FF + +bitmap2 = displayio.Bitmap(chartWidth * 2, chartHeight * 2, 1) # create bitmap2 +tileGrid2 = displayio.TileGrid( + bitmap2, pixel_shader=palette2, x=150, y=10 +) # Add bitmap2 to tilegrid2 +mySparkline2 = Sparkline( + width=chartWidth * 2, + height=chartHeight * 2, + max_items=10, + yMin=0, + yMax=1, + x=150, + y=10, + color=0xFF00FF, +) + + +# Setup the third bitmap and third sparkline +# mySparkline3 contains a maximum of 10 items +# since yMin and yMax are not specified, mySparkline3 uses autoranging for both the top and bottom of the y-axis. +# Note1: Any unspecified edge limit (yMin or yMax) will autorange that edge based on the data in the list. +# Note2: You can read back the value of the y-axis limits by using mySparkline3.yBottom or mySparkline3.yTop + + +palette3 = displayio.Palette(1) # color palette used for bitmap (one color) +palette3[0] = 0x11FF44 +bitmap3 = displayio.Bitmap(DISPLAY_WIDTH - 30, chartHeight * 2, 1) # create bitmap3 +tileGrid3 = displayio.TileGrid( + bitmap3, pixel_shader=palette3, x=0, y=120 +) # Add bitmap3 to tilegrid3 + +mySparkline3 = Sparkline( + width=DISPLAY_WIDTH - 30, + height=chartHeight * 2, + max_items=10, + x=0, + y=120, + color=0xFFFFFF, +) + + +# Initialize the y-axis labels for mySparkline3 with no text +textLabel3a = label.Label( + font=font, text="", color=0x11FF44, max_glyphs=20 +) # yTop label +textLabel3a.anchor_point = (0, 0.5) # set the anchorpoint +textLabel3a.anchored_position = ( + mySparkline3.width, + 120, +) # set the text anchored position to the upper right of the graph + +textLabel3b = label.Label( + font=font, text="", color=0x11FF44, max_glyphs=20 +) # yTop label +textLabel3b.anchor_point = (0, 0.5) # set the anchorpoint +textLabel3b.anchored_position = ( + mySparkline3.width, + 120 + mySparkline3.height, +) # set the text anchored position to the upper right of the graph + + +# Create a group to hold the three bitmap TileGrids and the three sparklines and +# append them into the group (myGroup) +# +# Note: In cases where display elements will overlap, then the order the elements are added to the +# group will set which is on top. Latter elements are displayed on top of former elemtns. +myGroup = displayio.Group(max_size=20) + +myGroup.append(mySparkline1) +myGroup.append(textLabel1a) +myGroup.append(textLabel1b) + +myGroup.append(tileGrid2) +myGroup.append(mySparkline2) + +myGroup.append(tileGrid3) +myGroup.append(mySparkline3) +myGroup.append(textLabel3a) +myGroup.append(textLabel3b) + + +# Display myGroup that contains all the bitmap TileGrids and sparklines +display.show(myGroup) + + +i = 0 # This is a counter for changing the random values for mySparkline3 + +# Start the main loop +while True: + + # add_value: add a new value to a sparkline + # Note: The y-range for mySparkline1 is set to -1 to 1.25, so all these random + # values (between 0 and 1) will fit within the visible range of this sparkline + mySparkline1.add_value(random.uniform(0, 1)) + + # Note: For mySparkline2, the y-axis range is set from 0 to 1. + # With the random values set between -1 and +2, the values will sometimes + # be out of the y-range. This example shows how the fixed y-range (0 to 1) + # will "clip" values (it will not display them) that are above or below the y-range. + mySparkline2.add_value(random.uniform(-1, 2)) + + # mySparkline3 is set autoranging for the top and bottom of the Y-axis + + # In this example, for 15 values, this adds points in the range from 0 to 1. + # Then, for the next 15 values, it adds points in the range of 0 to 10. + # This is to highlight the autoranging of the y-axis. + # Notice how the y-axis labels show that the y-scale is changing. + # + # An exercise for the reader: You can set only one or the other sparkline axis + # to autoranging by setting its value to None. + if i < 15: + mySparkline3.add_value(random.uniform(0, 1)) + else: + mySparkline3.add_value(random.uniform(0, 10)) + textLabel3a.text = str(mySparkline3.yTop) + textLabel3b.text = str(mySparkline3.yBottom) + i += 1 # increment the counter + if i > 30: # After 30 times through the loop, reset the counter + i = 0 + + # Turn off auto_refresh to prevent partial updates of the screen during updates + # of the sparkline drawing + display.auto_refresh = False + # Update all the sparklines + mySparkline1.update() + mySparkline2.update() + mySparkline3.update() + # Turn on auto_refresh for the display + display.auto_refresh = True + + # The display seems to be less jittery if a small sleep time is provided + # You can adjust this to see if it has any effect + time.sleep(0.01) + + # Uncomment the next line to print the amount of available memory + # print('memory free: {}'.format(gc.mem_free())) From 2ba35dbb897e3c52d0edfb90072b4e02d0a6a1bd Mon Sep 17 00:00:00 2001 From: FoamyGuy Date: Tue, 21 Jul 2020 18:14:36 -0500 Subject: [PATCH 03/17] update the simpletest to generalize the display setup --- .../display_shapes_sparkline_simpletest.py | 102 +++++++++--------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index 46c2c5e..5c637dc 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -29,67 +29,69 @@ import random import time from adafruit_display_shapes.sparkline import Sparkline -from adafruit_ili9341 import ILI9341 + from adafruit_display_text import label -import gc # from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class - -# Setup the LCD display - -displayio.release_displays() - - -# setup the SPI bus -spi = board.SPI() -tft_cs = board.D9 # arbitrary, pin not used -tft_dc = board.D10 -tft_backlight = board.D12 -tft_reset = board.D11 - -while not spi.try_lock(): - spi.configure(baudrate=32000000) - pass -spi.unlock() - -display_bus = displayio.FourWire( - spi, - command=tft_dc, - chip_select=tft_cs, - reset=tft_reset, - baudrate=32000000, - polarity=1, - phase=1, -) - -print("spi.frequency: {}".format(spi.frequency)) - -# Number of pixels in the display -DISPLAY_WIDTH = 320 -DISPLAY_HEIGHT = 240 - -# create the display -display = ILI9341( - display_bus, - width=DISPLAY_WIDTH, - height=DISPLAY_HEIGHT, - rotation=180, - auto_refresh=True, - native_frames_per_second=90, -) - -# reset the display to show nothing. -display.show(None) +if "DISPLAY" not in dir(board): + # Setup the LCD display with driver + from adafruit_ili9341 import ILI9341 + + displayio.release_displays() + + # setup the SPI bus + spi = board.SPI() + tft_cs = board.D9 # arbitrary, pin not used + tft_dc = board.D10 + tft_backlight = board.D12 + tft_reset = board.D11 + + while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass + spi.unlock() + + display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, + ) + + print("spi.frequency: {}".format(spi.frequency)) + + # Number of pixels in the display + DISPLAY_WIDTH = 320 + DISPLAY_HEIGHT = 240 + + # create the display + display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, + auto_refresh=True, + native_frames_per_second=90, + ) + + # reset the display to show nothing. + display.show(None) +else: + # built-in display + display = board.DISPLAY ########################################## # Create background bitmaps and sparklines ########################################## # Baseline size of the sparkline chart, in pixels. -chartWidth = DISPLAY_WIDTH -chartHeight = DISPLAY_HEIGHT +chartWidth = display.width +chartHeight = display.height # mySparkline1 uses a vertical y range between 0 to 10 and will contain a maximum of 40 items From 8de933e5a4b687c78b9b0b5ab0d25e0677069165 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Tue, 21 Jul 2020 20:39:59 -0500 Subject: [PATCH 04/17] Deleted unnecessary import in sparkline_simpletest --- examples/display_shapes_sparkline_simpletest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index 5c637dc..407384f 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -30,7 +30,6 @@ import time from adafruit_display_shapes.sparkline import Sparkline -from adafruit_display_text import label # from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class From 0a70198ea437ef8c07334cb1b26816783f8bddcc Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 10:59:32 -0500 Subject: [PATCH 05/17] Set for auto update upon add_value, updated examples with display checking --- adafruit_display_shapes/sparkline.py | 2 +- .../display_shapes_sparkline_simpletest.py | 20 ++- examples/display_shapes_sparkline_ticks.py | 112 ++++++++--------- examples/display_shapes_sparkline_triple.py | 115 +++++++++--------- 4 files changed, 120 insertions(+), 129 deletions(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index 125facc..084107e 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -54,7 +54,7 @@ def add_value(self, value): ): # if list is full, remove the first item self._spark_list.pop(0) self._spark_list.append(value) - # self.update() + self.update() @staticmethod def _xintercept( diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index 407384f..ad0a333 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -30,12 +30,10 @@ import time from adafruit_display_shapes.sparkline import Sparkline - - -# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class - if "DISPLAY" not in dir(board): # Setup the LCD display with driver + # You may need to change this to match the display driver for the chipset + # used on your display from adafruit_ili9341 import ILI9341 displayio.release_displays() @@ -73,7 +71,7 @@ display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, - rotation=180, + rotation=180, # The rotation can be adjusted to match your configuration. auto_refresh=True, native_frames_per_second=90, ) @@ -92,36 +90,36 @@ chartWidth = display.width chartHeight = display.height - # mySparkline1 uses a vertical y range between 0 to 10 and will contain a maximum of 40 items mySparkline1 = Sparkline( width=chartWidth, height=chartHeight, max_items=40, yMin=0, yMax=10, x=0, y=0 ) - # Create a group to hold the sparkline and append the sparkline into the group (myGroup) # # Note: In cases where display elements will overlap, then the order the elements are added to the # group will set which is on top. Latter elements are displayed on top of former elemtns. myGroup = displayio.Group(max_size=1) +# add the sparkline into myGroup myGroup.append(mySparkline1) -# Display myGroup that contains the sparkline +# Add myGroup (containing the sparkline) to the display display.show(myGroup) - # Start the main loop while True: + # turn off the auto_refresh of the display while modifying the sparkline + display.auto_refresh = False + # add_value: add a new value to a sparkline # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random # values (between 0 and 10) will fit within the visible range of this sparkline mySparkline1.add_value(random.uniform(0, 10)) - display.auto_refresh = False - mySparkline1.update() + # turn the display auto_refresh back on display.auto_refresh = True # The display seems to be less jittery if a small sleep time is provided diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py index d871416..ff141c2 100755 --- a/examples/display_shapes_sparkline_ticks.py +++ b/examples/display_shapes_sparkline_ticks.py @@ -34,64 +34,65 @@ from adafruit_display_shapes.line import Line from adafruit_display_shapes.rect import Rect -import gc - -# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class - - -# Setup the LCD display - -displayio.release_displays() - - -# setup the SPI bus -spi = board.SPI() -tft_cs = board.D9 # arbitrary, pin not used -tft_dc = board.D10 -tft_backlight = board.D12 -tft_reset = board.D11 - -while not spi.try_lock(): - spi.configure(baudrate=32000000) - pass -spi.unlock() - -display_bus = displayio.FourWire( - spi, - command=tft_dc, - chip_select=tft_cs, - reset=tft_reset, - baudrate=32000000, - polarity=1, - phase=1, -) +if "DISPLAY" not in dir(board): + # Setup the LCD display with driver + # You may need to change this to match the display driver for the chipset + # used on your display + from adafruit_ili9341 import ILI9341 + + displayio.release_displays() + + # setup the SPI bus + spi = board.SPI() + tft_cs = board.D9 # arbitrary, pin not used + tft_dc = board.D10 + tft_backlight = board.D12 + tft_reset = board.D11 + + while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass + spi.unlock() + + display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, + ) -print("spi.frequency: {}".format(spi.frequency)) + print("spi.frequency: {}".format(spi.frequency)) -# Number of pixels in the display -DISPLAY_WIDTH = 320 -DISPLAY_HEIGHT = 240 + # Number of pixels in the display + DISPLAY_WIDTH = 320 + DISPLAY_HEIGHT = 240 -# create the display -display = ILI9341( - display_bus, - width=DISPLAY_WIDTH, - height=DISPLAY_HEIGHT, - rotation=180, - auto_refresh=True, - native_frames_per_second=90, -) + # create the display + display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, # The rotation can be adjusted to match your configuration. + auto_refresh=True, + native_frames_per_second=90, + ) -# reset the display to show nothing. -display.show(None) + # reset the display to show nothing. + display.show(None) +else: + # built-in display + display = board.DISPLAY ########################################## # Create background bitmaps and sparklines ########################################## # Baseline size of the sparkline chart, in pixels. -chartWidth = 270 -chartHeight = 180 +chartWidth = display.width-50 +chartHeight = display.height-50 font = terminalio.FONT @@ -168,24 +169,21 @@ ) ) - -# Display myGroup that contains all the bitmap TileGrids and sparklines +# Set the display to show myGroup that contains the sparkline and other graphics display.show(myGroup) - # Start the main loop while True: + # Turn off auto_refresh to prevent partial updates of the screen during updates + # of the sparkline drawing + display.auto_refresh = False + # add_value: add a new value to a sparkline # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random # values (between 0 and 10) will fit within the visible range of this sparkline mySparkline1.add_value(random.uniform(0, 10)) - # Turn off auto_refresh to prevent partial updates of the screen during updates - # of the sparkline drawing - display.auto_refresh = False - # Update all the sparklines - mySparkline1.update() # Turn on auto_refresh for the display display.auto_refresh = True @@ -193,5 +191,3 @@ # You can adjust this to see if it has any effect time.sleep(0.01) - # Uncomment the next line to print the amount of available memory - # print('memory free: {}'.format(gc.mem_free())) diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index 1fdcb1a..3509dbf 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -34,54 +34,57 @@ import gc -# from sparkline import sparkline # use this if sparkline.py is used to define the sparkline Class - - -# Setup the LCD display - -displayio.release_displays() - - -# setup the SPI bus -spi = board.SPI() -tft_cs = board.D9 # arbitrary, pin not used -tft_dc = board.D10 -tft_backlight = board.D12 -tft_reset = board.D11 - -while not spi.try_lock(): - spi.configure(baudrate=32000000) - pass -spi.unlock() - -display_bus = displayio.FourWire( - spi, - command=tft_dc, - chip_select=tft_cs, - reset=tft_reset, - baudrate=32000000, - polarity=1, - phase=1, -) - -print("spi.frequency: {}".format(spi.frequency)) - -# Number of pixels in the display -DISPLAY_WIDTH = 320 -DISPLAY_HEIGHT = 240 - -# create the display -display = ILI9341( - display_bus, - width=DISPLAY_WIDTH, - height=DISPLAY_HEIGHT, - rotation=180, - auto_refresh=True, - native_frames_per_second=90, -) - -# reset the display to show nothing. -display.show(None) +if "DISPLAY" not in dir(board): + # Setup the LCD display with driver + # You may need to change this to match the display driver for the chipset + # used on your display + from adafruit_ili9341 import ILI9341 + + displayio.release_displays() + + # setup the SPI bus + spi = board.SPI() + tft_cs = board.D9 # arbitrary, pin not used + tft_dc = board.D10 + tft_backlight = board.D12 + tft_reset = board.D11 + + while not spi.try_lock(): + spi.configure(baudrate=32000000) + pass + spi.unlock() + + display_bus = displayio.FourWire( + spi, + command=tft_dc, + chip_select=tft_cs, + reset=tft_reset, + baudrate=32000000, + polarity=1, + phase=1, + ) + + print("spi.frequency: {}".format(spi.frequency)) + + # Number of pixels in the display + DISPLAY_WIDTH = 320 + DISPLAY_HEIGHT = 240 + + # create the display + display = ILI9341( + display_bus, + width=DISPLAY_WIDTH, + height=DISPLAY_HEIGHT, + rotation=180, # The rotation can be adjusted to match your configuration. + auto_refresh=True, + native_frames_per_second=90, + ) + + # reset the display to show nothing. + display.show(None) +else: + # built-in display + display = board.DISPLAY ########################################## # Create background bitmaps and sparklines @@ -165,7 +168,6 @@ color=0xFFFFFF, ) - # Initialize the y-axis labels for mySparkline3 with no text textLabel3a = label.Label( font=font, text="", color=0x11FF44, max_glyphs=20 @@ -205,16 +207,18 @@ myGroup.append(textLabel3a) myGroup.append(textLabel3b) - -# Display myGroup that contains all the bitmap TileGrids and sparklines +# Set the display to show myGroup that contains all the bitmap TileGrids and sparklines display.show(myGroup) - i = 0 # This is a counter for changing the random values for mySparkline3 # Start the main loop while True: + # Turn off auto_refresh to prevent partial updates of the screen during updates + # of the sparklines + display.auto_refresh = False + # add_value: add a new value to a sparkline # Note: The y-range for mySparkline1 is set to -1 to 1.25, so all these random # values (between 0 and 1) will fit within the visible range of this sparkline @@ -245,13 +249,6 @@ if i > 30: # After 30 times through the loop, reset the counter i = 0 - # Turn off auto_refresh to prevent partial updates of the screen during updates - # of the sparkline drawing - display.auto_refresh = False - # Update all the sparklines - mySparkline1.update() - mySparkline2.update() - mySparkline3.update() # Turn on auto_refresh for the display display.auto_refresh = True From 28dc4ae54042f3ba83b7742370e03fc91d8cc81b Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 11:12:17 -0500 Subject: [PATCH 06/17] Ran black on examples --- examples/display_shapes_sparkline_simpletest.py | 6 +++--- examples/display_shapes_sparkline_ticks.py | 7 +++---- examples/display_shapes_sparkline_triple.py | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index ad0a333..4a4d9e8 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -71,7 +71,7 @@ display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, - rotation=180, # The rotation can be adjusted to match your configuration. + rotation=180, # The rotation can be adjusted to match your configuration. auto_refresh=True, native_frames_per_second=90, ) @@ -105,7 +105,7 @@ myGroup.append(mySparkline1) -# Add myGroup (containing the sparkline) to the display +# Add myGroup (containing the sparkline) to the display display.show(myGroup) # Start the main loop @@ -119,7 +119,7 @@ # values (between 0 and 10) will fit within the visible range of this sparkline mySparkline1.add_value(random.uniform(0, 10)) - # turn the display auto_refresh back on + # turn the display auto_refresh back on display.auto_refresh = True # The display seems to be less jittery if a small sleep time is provided diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py index ff141c2..88cbb71 100755 --- a/examples/display_shapes_sparkline_ticks.py +++ b/examples/display_shapes_sparkline_ticks.py @@ -75,7 +75,7 @@ display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, - rotation=180, # The rotation can be adjusted to match your configuration. + rotation=180, # The rotation can be adjusted to match your configuration. auto_refresh=True, native_frames_per_second=90, ) @@ -91,8 +91,8 @@ ########################################## # Baseline size of the sparkline chart, in pixels. -chartWidth = display.width-50 -chartHeight = display.height-50 +chartWidth = display.width - 50 +chartHeight = display.height - 50 font = terminalio.FONT @@ -190,4 +190,3 @@ # The display seems to be less jittery if a small sleep time is provided # You can adjust this to see if it has any effect time.sleep(0.01) - diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index 3509dbf..d83a4a7 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -75,7 +75,7 @@ display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, - rotation=180, # The rotation can be adjusted to match your configuration. + rotation=180, # The rotation can be adjusted to match your configuration. auto_refresh=True, native_frames_per_second=90, ) From 7fe45cbd2323da077037c9824beabe52ff28fd90 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 11:32:05 -0500 Subject: [PATCH 07/17] Updates for pylint, ran black --- adafruit_display_shapes/sparkline.py | 41 ++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index 084107e..d44455c 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -4,20 +4,36 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# A sparkline is a scrolling line graph, where any values added to sparkline using ` +# add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# The `sparkline` class creates an element suitable for adding to the display using +# `display.show(mySparkline)` # or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be included in the graph. -# When additional elements are added to the sparkline and the number of items has exceeded max_items, -# any excess values are removed from the left of the graph, and new values are added to the right. +# When creating the sparkline, identify the number of `max_items` that will be +# included in the graph. When additional elements are added to the sparkline and +# the number of items has exceeded max_items, any excess values are removed from +# the left of the graph, and new values are added to the right. import displayio from adafruit_display_shapes.line import Line class Sparkline(displayio.Group): + # pylint: disable=invalid-name + """ A sparkline graph. + + : param width: Width of the sparkline graph in pixels + : param height: Height of the sparkline graph in pixels + : param max_items: Maximum number of values housed in the sparkline + : param yMin: Lower range for the y-axis. Set to None for autorange. + : param yMax: Upper range for the y-axis. Set to None for autorange. + : param x: X-position on the screen, in pixels + : param y: Y-position on the screen, in pixels + : param color: Line color, the default value is 0xFFFFFF (WHITE) + """ + def __init__( self, width, @@ -48,6 +64,11 @@ def __init__( ) # self is a group of lines def add_value(self, value): + """ Add a value to the sparkline. + + : param value: The value to be added to the sparkline + """ + if value is not None: if ( len(self._spark_list) >= self._max_items @@ -77,16 +98,20 @@ def _plotLine(self, x1, last_value, x2, value, yBottom, yTop): y1 = int(self.height * (yTop - last_value) / (yTop - yBottom)) self.append(Line(x1, y1, x2, y2, self.color)) # plot the line + # pylint: disable=invalid-name, too-many-branches + def update(self): - # What to do if there is 0 or 1 element? + """Update the drawing of the sparkline + + """ # get the y range - if self.yMin == None: + if self.yMin is None: self.yBottom = min(self._spark_list) else: self.yBottom = self.yMin - if self.yMax == None: + if self.yMax is None: self.yTop = max(self._spark_list) else: self.yTop = self.yMax From bf0ac9e925d124df592068dbc11fce5563ead103 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 11:45:47 -0500 Subject: [PATCH 08/17] updated for pylint --- adafruit_display_shapes/sparkline.py | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index d44455c..859b5f7 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -15,13 +15,31 @@ # included in the graph. When additional elements are added to the sparkline and # the number of items has exceeded max_items, any excess values are removed from # the left of the graph, and new values are added to the right. +""" +`sparkline` +================================================================================ + +Various common shapes for use with displayio - Sparkline! + + +* Author(s): Kevin Matocha + +Implementation Notes +-------------------- + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases + +""" import displayio from adafruit_display_shapes.line import Line class Sparkline(displayio.Group): - # pylint: disable=invalid-name + # pylint: disable=invalid-name, too-many-arguments """ A sparkline graph. : param width: Width of the sparkline graph in pixels @@ -54,8 +72,12 @@ def __init__( self._spark_list = [] # list containing the values self.yMin = yMin # minimum of y-axis (None: autoscale) self.yMax = yMax # maximum of y-axis (None: autoscale) - self.yBottom = yMin # yBottom: The actual minimum value of the vertical scale, will be updated if autorange - self.yTop = yMax # yTop: The actual minimum value of the vertical scale, will be updated if autorange + self.yBottom = yMin + # yBottom: The actual minimum value of the vertical scale, will be + # updated if autorange + self.yTop = yMax + # yTop: The actual minimum value of the vertical scale, will be + # updated if autorange self._x = x self._y = y @@ -65,7 +87,6 @@ def __init__( def add_value(self, value): """ Add a value to the sparkline. - : param value: The value to be added to the sparkline """ @@ -121,7 +142,7 @@ def update(self): len(self._spark_list) - 1 ) # this is a float, only make int when plotting the line - for i in range(len(self)): # remove all items from the current group + for _ in range(len(self)): # remove all items from the current group self.pop() for count, value in enumerate(self._spark_list): @@ -192,4 +213,7 @@ def update(self): last_value = value # store value for the next iteration def values(self): + """Returns the values displayed on the sparkline + """ + return self._spark_list From deb9a2c3070b14ff3fff78b3842a0045af7368a2 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 11:52:56 -0500 Subject: [PATCH 09/17] pylint fixes --- adafruit_display_shapes/sparkline.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index 859b5f7..4437f34 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -98,6 +98,7 @@ def add_value(self, value): self._spark_list.append(value) self.update() + # pylint: disable=no-else-return @staticmethod def _xintercept( x1, y1, x2, y2, horizontalY @@ -119,7 +120,7 @@ def _plotLine(self, x1, last_value, x2, value, yBottom, yTop): y1 = int(self.height * (yTop - last_value) / (yTop - yBottom)) self.append(Line(x1, y1, x2, y2, self.color)) # plot the line - # pylint: disable=invalid-name, too-many-branches + # pylint: disable=invalid-name, too-many-branches, too-many-nested-blocks def update(self): """Update the drawing of the sparkline From 3367ba55ba03e8c3413510e36d42155cb82d44bf Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 12:07:32 -0500 Subject: [PATCH 10/17] Updated examples for pylint --- .../display_shapes_sparkline_simpletest.py | 34 ++++++++------ examples/display_shapes_sparkline_ticks.py | 23 ++++++---- examples/display_shapes_sparkline_triple.py | 45 +++++++++++-------- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index 4a4d9e8..7fafd6a 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -4,14 +4,18 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# A sparkline is a scrolling line graph, where any values added to sparkline using +# `add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` +# The `sparkline` class creates an element suitable for adding to the display using +# `display.show(mySparkline)` # or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be included in the graph. -# When additional elements are added to the sparkline and the number of items has exceeded max_items, -# any excess values are removed from the left of the graph, and new values are added to the right. +# When creating the sparkline, identify the number of `max_items` that will be +# included in the graph. +# When additional elements are added to the sparkline and the number of items has +# exceeded max_items, any excess values are removed from the left of the graph, +# and new values are added to the right. # The following is an example that shows the @@ -23,11 +27,12 @@ # add new values to sparkline `add_value` # update the sparklines `update` +import time +import random import board import displayio -import terminalio -import random -import time + + from adafruit_display_shapes.sparkline import Sparkline if "DISPLAY" not in dir(board): @@ -47,7 +52,7 @@ while not spi.try_lock(): spi.configure(baudrate=32000000) - pass + spi.unlock() display_bus = displayio.FourWire( @@ -90,15 +95,18 @@ chartWidth = display.width chartHeight = display.height -# mySparkline1 uses a vertical y range between 0 to 10 and will contain a maximum of 40 items +# mySparkline1 uses a vertical y range between 0 to 10 and will contain a +# maximum of 40 items mySparkline1 = Sparkline( width=chartWidth, height=chartHeight, max_items=40, yMin=0, yMax=10, x=0, y=0 ) -# Create a group to hold the sparkline and append the sparkline into the group (myGroup) +# Create a group to hold the sparkline and append the sparkline into the +# group (myGroup) # -# Note: In cases where display elements will overlap, then the order the elements are added to the -# group will set which is on top. Latter elements are displayed on top of former elemtns. +# Note: In cases where display elements will overlap, then the order the elements +# are added to the group will set which is on top. Latter elements are displayed +# on top of former elemtns. myGroup = displayio.Group(max_size=1) # add the sparkline into myGroup diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py index 88cbb71..e34bf81 100755 --- a/examples/display_shapes_sparkline_ticks.py +++ b/examples/display_shapes_sparkline_ticks.py @@ -4,14 +4,17 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# A sparkline is a scrolling line graph, where any values added to sparkline +# using `add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` -# or adding to a `displayio.Group` to be displayed. +# The `sparkline` class creates an element suitable for adding to the display +# using `display.show(mySparkline)` or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be included in the graph. -# When additional elements are added to the sparkline and the number of items has exceeded max_items, -# any excess values are removed from the left of the graph, and new values are added to the right. +# When creating the sparkline, identify the number of `max_items` that will be +# included in the graph. +# When additional elements are added to the sparkline and the number of items +# has exceeded max_items, any excess values are removed from the left of the +# graph, and new values are added to the right. # The following is an example that shows the @@ -100,7 +103,8 @@ # Setup the first bitmap and sparkline # This sparkline has no background bitmap -# mySparkline1 uses a vertical y range between 0 to 10 and will contain a maximum of 40 items +# mySparkline1 uses a vertical y range between 0 to 10 and will contain a +# maximum of 40 items mySparkline1 = Sparkline( width=chartWidth, height=chartHeight, @@ -142,8 +146,9 @@ # Create a group to hold the sparkline, text, rectangle and tickmarks # append them into the group (myGroup) # -# Note: In cases where display elements will overlap, then the order the elements are added to the -# group will set which is on top. Latter elements are displayed on top of former elemtns. +# Note: In cases where display elements will overlap, then the order the +# elements are added to the group will set which is on top. Latter elements +# are displayed on top of former elemtns. myGroup = displayio.Group(max_size=20) diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index d83a4a7..e15f3c1 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -4,14 +4,17 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline using `add_value` are plotted. +# A sparkline is a scrolling line graph, where any values added to sparkline +# using `add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display using `display.show(mySparkline)` -# or adding to a `displayio.Group` to be displayed. +# The `sparkline` class creates an element suitable for adding to the display +# using `display.show(mySparkline)` or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be included in the graph. -# When additional elements are added to the sparkline and the number of items has exceeded max_items, -# any excess values are removed from the left of the graph, and new values are added to the right. +# When creating the sparkline, identify the number of `max_items` that will be +# included in the graph. +# When additional elements are added to the sparkline and the number of items +# has exceeded max_items, any excess values are removed from the left of the +# graph, and new values are added to the right. # The following is an example that shows the @@ -23,11 +26,11 @@ # add new values to sparkline `add_value` # update the sparklines `update` +import random +import time import board import displayio import terminalio -import random -import time from adafruit_display_shapes.sparkline import Sparkline from adafruit_ili9341 import ILI9341 from adafruit_display_text import label @@ -75,7 +78,7 @@ display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, - rotation=180, # The rotation can be adjusted to match your configuration. + rotation=180, # The rotation can be adjusted to match your configuration. auto_refresh=True, native_frames_per_second=90, ) @@ -124,7 +127,8 @@ # Setup the second bitmap and sparkline -# mySparkline2 uses a vertical y range between 0 to 1, and will contain a maximum of 10 items +# mySparkline2 uses a vertical y range between 0 to 1, and will contain a +# maximum of 10 items # palette2 = displayio.Palette(1) # color palette used for bitmap2 (one color) palette2[0] = 0x0000FF @@ -147,9 +151,12 @@ # Setup the third bitmap and third sparkline # mySparkline3 contains a maximum of 10 items -# since yMin and yMax are not specified, mySparkline3 uses autoranging for both the top and bottom of the y-axis. -# Note1: Any unspecified edge limit (yMin or yMax) will autorange that edge based on the data in the list. -# Note2: You can read back the value of the y-axis limits by using mySparkline3.yBottom or mySparkline3.yTop +# since yMin and yMax are not specified, mySparkline3 uses autoranging for both +# the top and bottom of the y-axis. +# Note1: Any unspecified edge limit (yMin or yMax) will autorange that edge based +# on the data in the list. +# Note2: You can read back the value of the y-axis limits by using +# mySparkline3.yBottom or mySparkline3.yTop palette3 = displayio.Palette(1) # color palette used for bitmap (one color) @@ -187,12 +194,12 @@ 120 + mySparkline3.height, ) # set the text anchored position to the upper right of the graph - # Create a group to hold the three bitmap TileGrids and the three sparklines and # append them into the group (myGroup) # -# Note: In cases where display elements will overlap, then the order the elements are added to the -# group will set which is on top. Latter elements are displayed on top of former elemtns. +# Note: In cases where display elements will overlap, then the order the elements +# are added to the group will set which is on top. Latter elements are displayed +# on top of former elemtns. myGroup = displayio.Group(max_size=20) myGroup.append(mySparkline1) @@ -207,7 +214,8 @@ myGroup.append(textLabel3a) myGroup.append(textLabel3b) -# Set the display to show myGroup that contains all the bitmap TileGrids and sparklines +# Set the display to show myGroup that contains all the bitmap TileGrids and +# sparklines display.show(myGroup) i = 0 # This is a counter for changing the random values for mySparkline3 @@ -227,7 +235,8 @@ # Note: For mySparkline2, the y-axis range is set from 0 to 1. # With the random values set between -1 and +2, the values will sometimes # be out of the y-range. This example shows how the fixed y-range (0 to 1) - # will "clip" values (it will not display them) that are above or below the y-range. + # will "clip" values (it will not display them) that are above or below the + # y-range. mySparkline2.add_value(random.uniform(-1, 2)) # mySparkline3 is set autoranging for the top and bottom of the Y-axis From a972ae531f9d445ad943743c3c3a51701f0d7426 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 12:10:01 -0500 Subject: [PATCH 11/17] Ran black --- .../display_shapes_sparkline_simpletest.py | 20 ++++++------- examples/display_shapes_sparkline_ticks.py | 16 +++++------ examples/display_shapes_sparkline_triple.py | 28 +++++++++---------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index 7fafd6a..f5a15ed 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -4,17 +4,17 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline using +# A sparkline is a scrolling line graph, where any values added to sparkline using # `add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display using +# The `sparkline` class creates an element suitable for adding to the display using # `display.show(mySparkline)` # or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be +# When creating the sparkline, identify the number of `max_items` that will be # included in the graph. -# When additional elements are added to the sparkline and the number of items has -# exceeded max_items, any excess values are removed from the left of the graph, +# When additional elements are added to the sparkline and the number of items has +# exceeded max_items, any excess values are removed from the left of the graph, # and new values are added to the right. @@ -52,7 +52,7 @@ while not spi.try_lock(): spi.configure(baudrate=32000000) - + spi.unlock() display_bus = displayio.FourWire( @@ -95,17 +95,17 @@ chartWidth = display.width chartHeight = display.height -# mySparkline1 uses a vertical y range between 0 to 10 and will contain a +# mySparkline1 uses a vertical y range between 0 to 10 and will contain a # maximum of 40 items mySparkline1 = Sparkline( width=chartWidth, height=chartHeight, max_items=40, yMin=0, yMax=10, x=0, y=0 ) -# Create a group to hold the sparkline and append the sparkline into the +# Create a group to hold the sparkline and append the sparkline into the # group (myGroup) # -# Note: In cases where display elements will overlap, then the order the elements -# are added to the group will set which is on top. Latter elements are displayed +# Note: In cases where display elements will overlap, then the order the elements +# are added to the group will set which is on top. Latter elements are displayed # on top of former elemtns. myGroup = displayio.Group(max_size=1) diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py index e34bf81..428bea5 100755 --- a/examples/display_shapes_sparkline_ticks.py +++ b/examples/display_shapes_sparkline_ticks.py @@ -4,16 +4,16 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline +# A sparkline is a scrolling line graph, where any values added to sparkline # using `add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display +# The `sparkline` class creates an element suitable for adding to the display # using `display.show(mySparkline)` or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be +# When creating the sparkline, identify the number of `max_items` that will be # included in the graph. -# When additional elements are added to the sparkline and the number of items -# has exceeded max_items, any excess values are removed from the left of the +# When additional elements are added to the sparkline and the number of items +# has exceeded max_items, any excess values are removed from the left of the # graph, and new values are added to the right. @@ -103,7 +103,7 @@ # Setup the first bitmap and sparkline # This sparkline has no background bitmap -# mySparkline1 uses a vertical y range between 0 to 10 and will contain a +# mySparkline1 uses a vertical y range between 0 to 10 and will contain a # maximum of 40 items mySparkline1 = Sparkline( width=chartWidth, @@ -146,8 +146,8 @@ # Create a group to hold the sparkline, text, rectangle and tickmarks # append them into the group (myGroup) # -# Note: In cases where display elements will overlap, then the order the -# elements are added to the group will set which is on top. Latter elements +# Note: In cases where display elements will overlap, then the order the +# elements are added to the group will set which is on top. Latter elements # are displayed on top of former elemtns. myGroup = displayio.Group(max_size=20) diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index e15f3c1..4ba4291 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -4,16 +4,16 @@ # See the bottom for a code example using the `sparkline` Class. # # File: display_shapes_sparkline.py -# A sparkline is a scrolling line graph, where any values added to sparkline +# A sparkline is a scrolling line graph, where any values added to sparkline # using `add_value` are plotted. # -# The `sparkline` class creates an element suitable for adding to the display +# The `sparkline` class creates an element suitable for adding to the display # using `display.show(mySparkline)` or adding to a `displayio.Group` to be displayed. # -# When creating the sparkline, identify the number of `max_items` that will be +# When creating the sparkline, identify the number of `max_items` that will be # included in the graph. -# When additional elements are added to the sparkline and the number of items -# has exceeded max_items, any excess values are removed from the left of the +# When additional elements are added to the sparkline and the number of items +# has exceeded max_items, any excess values are removed from the left of the # graph, and new values are added to the right. @@ -78,7 +78,7 @@ display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, - rotation=180, # The rotation can be adjusted to match your configuration. + rotation=180, # The rotation can be adjusted to match your configuration. auto_refresh=True, native_frames_per_second=90, ) @@ -127,7 +127,7 @@ # Setup the second bitmap and sparkline -# mySparkline2 uses a vertical y range between 0 to 1, and will contain a +# mySparkline2 uses a vertical y range between 0 to 1, and will contain a # maximum of 10 items # palette2 = displayio.Palette(1) # color palette used for bitmap2 (one color) @@ -151,11 +151,11 @@ # Setup the third bitmap and third sparkline # mySparkline3 contains a maximum of 10 items -# since yMin and yMax are not specified, mySparkline3 uses autoranging for both +# since yMin and yMax are not specified, mySparkline3 uses autoranging for both # the top and bottom of the y-axis. -# Note1: Any unspecified edge limit (yMin or yMax) will autorange that edge based +# Note1: Any unspecified edge limit (yMin or yMax) will autorange that edge based # on the data in the list. -# Note2: You can read back the value of the y-axis limits by using +# Note2: You can read back the value of the y-axis limits by using # mySparkline3.yBottom or mySparkline3.yTop @@ -197,8 +197,8 @@ # Create a group to hold the three bitmap TileGrids and the three sparklines and # append them into the group (myGroup) # -# Note: In cases where display elements will overlap, then the order the elements -# are added to the group will set which is on top. Latter elements are displayed +# Note: In cases where display elements will overlap, then the order the elements +# are added to the group will set which is on top. Latter elements are displayed # on top of former elemtns. myGroup = displayio.Group(max_size=20) @@ -214,7 +214,7 @@ myGroup.append(textLabel3a) myGroup.append(textLabel3b) -# Set the display to show myGroup that contains all the bitmap TileGrids and +# Set the display to show myGroup that contains all the bitmap TileGrids and # sparklines display.show(myGroup) @@ -235,7 +235,7 @@ # Note: For mySparkline2, the y-axis range is set from 0 to 1. # With the random values set between -1 and +2, the values will sometimes # be out of the y-range. This example shows how the fixed y-range (0 to 1) - # will "clip" values (it will not display them) that are above or below the + # will "clip" values (it will not display them) that are above or below the # y-range. mySparkline2.add_value(random.uniform(-1, 2)) From cf9551c885443477cb025afebe695dedfb55510e Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 12:15:16 -0500 Subject: [PATCH 12/17] Pylint updates and ran black --- examples/display_shapes_sparkline_ticks.py | 8 +++----- examples/display_shapes_sparkline_triple.py | 7 ------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py index 428bea5..9fef979 100755 --- a/examples/display_shapes_sparkline_ticks.py +++ b/examples/display_shapes_sparkline_ticks.py @@ -26,16 +26,15 @@ # add new values to sparkline `add_value` # update the sparklines `update` +import random +import time import board import displayio import terminalio -import random -import time from adafruit_display_shapes.sparkline import Sparkline -from adafruit_ili9341 import ILI9341 -from adafruit_display_text import label from adafruit_display_shapes.line import Line from adafruit_display_shapes.rect import Rect +from adafruit_display_text import label if "DISPLAY" not in dir(board): # Setup the LCD display with driver @@ -54,7 +53,6 @@ while not spi.try_lock(): spi.configure(baudrate=32000000) - pass spi.unlock() display_bus = displayio.FourWire( diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index 4ba4291..e8b4c56 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -32,11 +32,8 @@ import displayio import terminalio from adafruit_display_shapes.sparkline import Sparkline -from adafruit_ili9341 import ILI9341 from adafruit_display_text import label -import gc - if "DISPLAY" not in dir(board): # Setup the LCD display with driver # You may need to change this to match the display driver for the chipset @@ -54,7 +51,6 @@ while not spi.try_lock(): spi.configure(baudrate=32000000) - pass spi.unlock() display_bus = displayio.FourWire( @@ -264,6 +260,3 @@ # The display seems to be less jittery if a small sleep time is provided # You can adjust this to see if it has any effect time.sleep(0.01) - - # Uncomment the next line to print the amount of available memory - # print('memory free: {}'.format(gc.mem_free())) From 0289b8ab513aafbdab14fb09d46a3b7dc4c72b1d Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 13:08:11 -0500 Subject: [PATCH 13/17] sparkline.py Updated camelCase to snake_case --- adafruit_display_shapes/sparkline.py | 96 +++++++++---------- .../display_shapes_sparkline_simpletest.py | 2 +- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index 4437f34..595187f 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -39,14 +39,14 @@ class Sparkline(displayio.Group): - # pylint: disable=invalid-name, too-many-arguments + # pylint: disable=too-many-arguments """ A sparkline graph. : param width: Width of the sparkline graph in pixels : param height: Height of the sparkline graph in pixels : param max_items: Maximum number of values housed in the sparkline - : param yMin: Lower range for the y-axis. Set to None for autorange. - : param yMax: Upper range for the y-axis. Set to None for autorange. + : param y_min: Lower range for the y-axis. Set to None for autorange. + : param y_max: Upper range for the y-axis. Set to None for autorange. : param x: X-position on the screen, in pixels : param y: Y-position on the screen, in pixels : param color: Line color, the default value is 0xFFFFFF (WHITE) @@ -57,8 +57,8 @@ def __init__( width, height, max_items, - yMin=None, # None = autoscaling - yMax=None, # None = autoscaling + y_min=None, # None = autoscaling + y_max=None, # None = autoscaling x=0, y=0, color=0xFFFFFF, # line color, default is WHITE @@ -70,13 +70,13 @@ def __init__( self.color = color # self._max_items = max_items # maximum number of items in the list self._spark_list = [] # list containing the values - self.yMin = yMin # minimum of y-axis (None: autoscale) - self.yMax = yMax # maximum of y-axis (None: autoscale) - self.yBottom = yMin - # yBottom: The actual minimum value of the vertical scale, will be + self.y_min = y_min # minimum of y-axis (None: autoscale) + self.y_max = y_max # maximum of y-axis (None: autoscale) + self.y_bottom = y_min + # y_bottom: The actual minimum value of the vertical scale, will be # updated if autorange - self.yTop = yMax - # yTop: The actual minimum value of the vertical scale, will be + self.y_top = y_max + # y_top: The actual minimum value of the vertical scale, will be # updated if autorange self._x = x self._y = y @@ -101,23 +101,23 @@ def add_value(self, value): # pylint: disable=no-else-return @staticmethod def _xintercept( - x1, y1, x2, y2, horizontalY + x1, y1, x2, y2, horizontal_y ): # finds intercept of the line and a horizontal line at horizontalY slope = (y2 - y1) / (x2 - x1) b = y1 - slope * x1 - if slope == 0 and y1 != horizontalY: # does not intercept horizontalY + if slope == 0 and y1 != horizontal_y: # does not intercept horizontalY return None else: xint = ( - horizontalY - b + horizontal_y - b ) / slope # calculate the x-intercept at position y=horizontalY return int(xint) - def _plotLine(self, x1, last_value, x2, value, yBottom, yTop): + def _plotLine(self, x1, last_value, x2, value, y_bottom, y_top): - y2 = int(self.height * (yTop - value) / (yTop - yBottom)) - y1 = int(self.height * (yTop - last_value) / (yTop - yBottom)) + y2 = int(self.height * (y_top - value) / (y_top - y_bottom)) + y1 = int(self.height * (y_top - last_value) / (y_top - y_bottom)) self.append(Line(x1, y1, x2, y2, self.color)) # plot the line # pylint: disable=invalid-name, too-many-branches, too-many-nested-blocks @@ -128,15 +128,15 @@ def update(self): """ # get the y range - if self.yMin is None: - self.yBottom = min(self._spark_list) + if self.y_min is None: + self.y_bottom = min(self._spark_list) else: - self.yBottom = self.yMin + self.y_bottom = self.y_min - if self.yMax is None: - self.yTop = max(self._spark_list) + if self.y_max is None: + self.y_top = max(self._spark_list) else: - self.yTop = self.yMax + self.y_top = self.y_max if len(self._spark_list) > 2: xpitch = self.width / ( @@ -155,29 +155,29 @@ def update(self): # print("x1: {}, x2: {}".format(x1,x2)) - if (self.yBottom <= last_value <= self.yTop) and ( - self.yBottom <= value <= self.yTop + if (self.y_bottom <= last_value <= self.y_top) and ( + self.y_bottom <= value <= self.y_top ): # both points are in range, plot the line self._plotLine( - x1, last_value, x2, value, self.yBottom, self.yTop + x1, last_value, x2, value, self.y_bottom, self.y_top ) else: # at least one point is out of range, clip one or both ends the line - if ((last_value > self.yTop) and (value > self.yTop)) or ( - (last_value < self.yBottom) and (value < self.yBottom) + if ((last_value > self.y_top) and (value > self.y_top)) or ( + (last_value < self.y_bottom) and (value < self.y_bottom) ): # both points are on the same side out of range: don't draw anything pass else: - xintBottom = self._xintercept( - x1, last_value, x2, value, self.yBottom + xint_bottom = self._xintercept( + x1, last_value, x2, value, self.y_bottom ) # get possible new x intercept points - xintTop = self._xintercept( - x1, last_value, x2, value, self.yTop + xint_top = self._xintercept( + x1, last_value, x2, value, self.y_top ) # on the top and bottom of range - if (xintBottom is None) or ( - xintTop is None + if (xint_bottom is None) or ( + xint_top is None ): # out of range doublecheck pass else: @@ -188,27 +188,27 @@ def update(self): adj_value = value if value > last_value: # slope is positive - if xintBottom >= x1: # bottom is clipped - adj_x1 = xintBottom - adj_last_value = self.yBottom # y1 - if xintTop <= x2: # top is clipped - adj_x2 = xintTop - adj_value = self.yTop # y2 + if xint_bottom >= x1: # bottom is clipped + adj_x1 = xint_bottom + adj_last_value = self.y_bottom # y1 + if xint_top <= x2: # top is clipped + adj_x2 = xint_top + adj_value = self.y_top # y2 else: # slope is negative - if xintTop >= x1: # top is clipped - adj_x1 = xintTop - adj_last_value = self.yTop # y1 - if xintBottom <= x2: # bottom is clipped - adj_x2 = xintBottom - adj_value = self.yBottom # y2 + if xint_top >= x1: # top is clipped + adj_x1 = xint_top + adj_last_value = self.y_top # y1 + if xint_bottom <= x2: # bottom is clipped + adj_x2 = xint_bottom + adj_value = self.y_bottom # y2 self._plotLine( adj_x1, adj_last_value, adj_x2, adj_value, - self.yBottom, - self.yTop, + self.y_bottom, + self.y_top, ) last_value = value # store value for the next iteration diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index f5a15ed..3358226 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -98,7 +98,7 @@ # mySparkline1 uses a vertical y range between 0 to 10 and will contain a # maximum of 40 items mySparkline1 = Sparkline( - width=chartWidth, height=chartHeight, max_items=40, yMin=0, yMax=10, x=0, y=0 + width=chartWidth, height=chartHeight, max_items=40, y_min=0, y_max=10, x=0, y=0 ) # Create a group to hold the sparkline and append the sparkline into the From ab90cc115994fa3972ef723c08fc245886184d22 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 13:14:50 -0500 Subject: [PATCH 14/17] More updates of snake_case --- adafruit_display_shapes/sparkline.py | 66 ++++++++++++++-------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index 595187f..a98476d 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -101,12 +101,12 @@ def add_value(self, value): # pylint: disable=no-else-return @staticmethod def _xintercept( - x1, y1, x2, y2, horizontal_y + x_1, y_1, x_2, y_2, horizontal_y ): # finds intercept of the line and a horizontal line at horizontalY - slope = (y2 - y1) / (x2 - x1) - b = y1 - slope * x1 + slope = (y_2 - y_1) / (x_2 - x_1) + b = y_1 - slope * x_1 - if slope == 0 and y1 != horizontal_y: # does not intercept horizontalY + if slope == 0 and y_1 != horizontal_y: # does not intercept horizontalY return None else: xint = ( @@ -114,11 +114,11 @@ def _xintercept( ) / slope # calculate the x-intercept at position y=horizontalY return int(xint) - def _plotLine(self, x1, last_value, x2, value, y_bottom, y_top): + def _plotline(self, x_1, last_value, x_2, value, y_bottom, y_top): - y2 = int(self.height * (y_top - value) / (y_top - y_bottom)) - y1 = int(self.height * (y_top - last_value) / (y_top - y_bottom)) - self.append(Line(x1, y1, x2, y2, self.color)) # plot the line + y_2 = int(self.height * (y_top - value) / (y_top - y_bottom)) + y_1 = int(self.height * (y_top - last_value) / (y_top - y_bottom)) + self.append(Line(x_1, y_1, x_2, y_2, self.color)) # plot the line # pylint: disable=invalid-name, too-many-branches, too-many-nested-blocks @@ -150,16 +150,14 @@ def update(self): if count == 0: pass # don't draw anything for a first point else: - x2 = int(xpitch * count) - x1 = int(xpitch * (count - 1)) - - # print("x1: {}, x2: {}".format(x1,x2)) + x_2 = int(xpitch * count) + x_1 = int(xpitch * (count - 1)) if (self.y_bottom <= last_value <= self.y_top) and ( self.y_bottom <= value <= self.y_top ): # both points are in range, plot the line - self._plotLine( - x1, last_value, x2, value, self.y_bottom, self.y_top + self._plotline( + x_1, last_value, x_2, value, self.y_bottom, self.y_top ) else: # at least one point is out of range, clip one or both ends the line @@ -170,10 +168,10 @@ def update(self): pass else: xint_bottom = self._xintercept( - x1, last_value, x2, value, self.y_bottom + x_1, last_value, x_2, value, self.y_bottom ) # get possible new x intercept points xint_top = self._xintercept( - x1, last_value, x2, value, self.y_top + x_1, last_value, x_2, value, self.y_top ) # on the top and bottom of range if (xint_bottom is None) or ( @@ -182,30 +180,30 @@ def update(self): pass else: # Initialize the adjusted values as the baseline - adj_x1 = x1 + adj_x_1 = x_1 adj_last_value = last_value - adj_x2 = x2 + adj_x_2 = x_2 adj_value = value if value > last_value: # slope is positive - if xint_bottom >= x1: # bottom is clipped - adj_x1 = xint_bottom - adj_last_value = self.y_bottom # y1 - if xint_top <= x2: # top is clipped - adj_x2 = xint_top - adj_value = self.y_top # y2 + if xint_bottom >= x_1: # bottom is clipped + adj_x_1 = xint_bottom + adj_last_value = self.y_bottom # y_1 + if xint_top <= x_2: # top is clipped + adj_x_2 = xint_top + adj_value = self.y_top # y_2 else: # slope is negative - if xint_top >= x1: # top is clipped - adj_x1 = xint_top - adj_last_value = self.y_top # y1 - if xint_bottom <= x2: # bottom is clipped - adj_x2 = xint_bottom - adj_value = self.y_bottom # y2 - - self._plotLine( - adj_x1, + if xint_top >= x_1: # top is clipped + adj_x_1 = xint_top + adj_last_value = self.y_top # y_1 + if xint_bottom <= x_2: # bottom is clipped + adj_x_2 = xint_bottom + adj_value = self.y_bottom # y_2 + + self._plotline( + adj_x_1, adj_last_value, - adj_x2, + adj_x_2, adj_value, self.y_bottom, self.y_top, From d7dcab7b68e3ec696bb4194bf6e860d02917d2e4 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 13:31:13 -0500 Subject: [PATCH 15/17] updated examples camelCase to snake_case to match pylint requirements --- .../display_shapes_sparkline_simpletest.py | 24 +-- examples/display_shapes_sparkline_ticks.py | 90 +++++------ examples/display_shapes_sparkline_triple.py | 142 +++++++++--------- 3 files changed, 131 insertions(+), 125 deletions(-) diff --git a/examples/display_shapes_sparkline_simpletest.py b/examples/display_shapes_sparkline_simpletest.py index 3358226..2faa026 100755 --- a/examples/display_shapes_sparkline_simpletest.py +++ b/examples/display_shapes_sparkline_simpletest.py @@ -92,29 +92,29 @@ ########################################## # Baseline size of the sparkline chart, in pixels. -chartWidth = display.width -chartHeight = display.height +chart_width = display.width +chart_height = display.height -# mySparkline1 uses a vertical y range between 0 to 10 and will contain a +# sparkline1 uses a vertical y range between 0 to 10 and will contain a # maximum of 40 items -mySparkline1 = Sparkline( - width=chartWidth, height=chartHeight, max_items=40, y_min=0, y_max=10, x=0, y=0 +sparkline1 = Sparkline( + width=chart_width, height=chart_height, max_items=40, y_min=0, y_max=10, x=0, y=0 ) # Create a group to hold the sparkline and append the sparkline into the -# group (myGroup) +# group (my_group) # # Note: In cases where display elements will overlap, then the order the elements # are added to the group will set which is on top. Latter elements are displayed # on top of former elemtns. -myGroup = displayio.Group(max_size=1) +my_group = displayio.Group(max_size=1) -# add the sparkline into myGroup -myGroup.append(mySparkline1) +# add the sparkline into my_group +my_group.append(sparkline1) -# Add myGroup (containing the sparkline) to the display -display.show(myGroup) +# Add my_group (containing the sparkline) to the display +display.show(my_group) # Start the main loop while True: @@ -125,7 +125,7 @@ # add_value: add a new value to a sparkline # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random # values (between 0 and 10) will fit within the visible range of this sparkline - mySparkline1.add_value(random.uniform(0, 10)) + sparkline1.add_value(random.uniform(0, 10)) # turn the display auto_refresh back on display.auto_refresh = True diff --git a/examples/display_shapes_sparkline_ticks.py b/examples/display_shapes_sparkline_ticks.py index 9fef979..f05d892 100755 --- a/examples/display_shapes_sparkline_ticks.py +++ b/examples/display_shapes_sparkline_ticks.py @@ -92,88 +92,88 @@ ########################################## # Baseline size of the sparkline chart, in pixels. -chartWidth = display.width - 50 -chartHeight = display.height - 50 +chart_width = display.width - 50 +chart_height = display.height - 50 font = terminalio.FONT -lineColor = 0xFFFFFF +line_color = 0xFFFFFF # Setup the first bitmap and sparkline # This sparkline has no background bitmap # mySparkline1 uses a vertical y range between 0 to 10 and will contain a # maximum of 40 items -mySparkline1 = Sparkline( - width=chartWidth, - height=chartHeight, +sparkline1 = Sparkline( + width=chart_width, + height=chart_height, max_items=40, - yMin=0, - yMax=10, + y_min=0, + y_max=10, x=40, y=30, - color=lineColor, + color=line_color, ) # Label the y-axis range -textXOffset = -10 -textLabel1a = label.Label( - font=font, text=str(mySparkline1.yTop), color=lineColor +text_xoffset = -10 +text_label1a = label.Label( + font=font, text=str(sparkline1.y_top), color=line_color ) # yTop label -textLabel1a.anchor_point = (1, 0.5) # set the anchorpoint at right-center -textLabel1a.anchored_position = ( - mySparkline1.x + textXOffset, - mySparkline1.y, +text_label1a.anchor_point = (1, 0.5) # set the anchorpoint at right-center +text_label1a.anchored_position = ( + sparkline1.x + text_xoffset, + sparkline1.y, ) # set the text anchored position to the upper right of the graph -textLabel1b = label.Label( - font=font, text=str(mySparkline1.yBottom), color=lineColor +text_label1b = label.Label( + font=font, text=str(sparkline1.y_bottom), color=line_color ) # yTop label -textLabel1b.anchor_point = (1, 0.5) # set the anchorpoint at right-center -textLabel1b.anchored_position = ( - mySparkline1.x + textXOffset, - mySparkline1.y + chartHeight, +text_label1b.anchor_point = (1, 0.5) # set the anchorpoint at right-center +text_label1b.anchored_position = ( + sparkline1.x + text_xoffset, + sparkline1.y + chart_height, ) # set the text anchored position to the upper right of the graph -boundingRectangle = Rect( - mySparkline1.x, mySparkline1.y, chartWidth + 1, chartHeight + 1, outline=lineColor +bounding_rectangle = Rect( + sparkline1.x, sparkline1.y, chart_width + 1, chart_height + 1, outline=line_color ) # Create a group to hold the sparkline, text, rectangle and tickmarks -# append them into the group (myGroup) +# append them into the group (my_group) # # Note: In cases where display elements will overlap, then the order the # elements are added to the group will set which is on top. Latter elements # are displayed on top of former elemtns. -myGroup = displayio.Group(max_size=20) +my_group = displayio.Group(max_size=20) -myGroup.append(mySparkline1) -myGroup.append(textLabel1a) -myGroup.append(textLabel1b) -myGroup.append(boundingRectangle) +my_group.append(sparkline1) +my_group.append(text_label1a) +my_group.append(text_label1b) +my_group.append(bounding_rectangle) -totalTicks = 10 +total_ticks = 10 -for i in range(totalTicks + 1): - xStart = mySparkline1.x - 5 - xEnd = mySparkline1.x - yBoth = mySparkline1.y + i * int(round(chartHeight / (totalTicks))) - myGroup.append(Line(xStart, yBoth, xEnd, yBoth, color=lineColor)) -myGroup.append( +for i in range(total_ticks + 1): + x_start = sparkline1.x - 5 + x_end = sparkline1.x + y_both = sparkline1.y + i * int(round(chart_height / (total_ticks))) + my_group.append(Line(x_start, y_both, x_end, y_both, color=line_color)) +my_group.append( Line( - xStart, - mySparkline1.y + chartHeight, - xEnd, - mySparkline1.y + chartHeight, - color=lineColor, + x_start, + sparkline1.y + chart_height, + x_end, + sparkline1.y + chart_height, + color=line_color, ) ) -# Set the display to show myGroup that contains the sparkline and other graphics -display.show(myGroup) +# Set the display to show my_group that contains the sparkline and other graphics +display.show(my_group) # Start the main loop while True: @@ -185,7 +185,7 @@ # add_value: add a new value to a sparkline # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random # values (between 0 and 10) will fit within the visible range of this sparkline - mySparkline1.add_value(random.uniform(0, 10)) + sparkline1.add_value(random.uniform(0, 10)) # Turn on auto_refresh for the display display.auto_refresh = True diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index e8b4c56..af975c8 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -90,55 +90,61 @@ ########################################## # Baseline size of the sparkline chart, in pixels. -chartWidth = 50 -chartHeight = 50 +chart_width = 50 +chart_height = 50 font = terminalio.FONT # Setup the first bitmap and sparkline # This sparkline has no background bitmap -# mySparkline1 uses a vertical y range between -1 to +1.25 and will contain a maximum of 40 items -mySparkline1 = Sparkline( - width=chartWidth, height=chartHeight, max_items=40, yMin=-1, yMax=1.25, x=10, y=10 +# sparkline1 uses a vertical y range between -1 to +1.25 and will contain a maximum of 40 items +sparkline1 = Sparkline( + width=chart_width, + height=chart_height, + max_items=40, + y_min=-1, + y_max=1.25, + x=10, + y=10, ) # Label the y-axis range -textLabel1a = label.Label( - font=font, text=str(mySparkline1.yTop), color=0xFFFFFF -) # yTop label -textLabel1a.anchor_point = (0, 0.5) # set the anchorpoint -textLabel1a.anchored_position = ( - 10 + chartWidth, +text_label1a = label.Label( + font=font, text=str(sparkline1.y_top), color=0xFFFFFF +) # y_top label +text_label1a.anchor_point = (0, 0.5) # set the anchorpoint +text_label1a.anchored_position = ( + 10 + chart_width, 10, ) # set the text anchored position to the upper right of the graph -textLabel1b = label.Label( - font=font, text=str(mySparkline1.yBottom), color=0xFFFFFF -) # yTop label -textLabel1b.anchor_point = (0, 0.5) # set the anchorpoint -textLabel1b.anchored_position = ( - 10 + chartWidth, - 10 + chartHeight, +text_label1b = label.Label( + font=font, text=str(sparkline1.y_bottom), color=0xFFFFFF +) # y_bottom label +text_label1b.anchor_point = (0, 0.5) # set the anchorpoint +text_label1b.anchored_position = ( + 10 + chart_width, + 10 + chart_height, ) # set the text anchored position to the upper right of the graph # Setup the second bitmap and sparkline -# mySparkline2 uses a vertical y range between 0 to 1, and will contain a +# sparkline2 uses a vertical y range between 0 to 1, and will contain a # maximum of 10 items # palette2 = displayio.Palette(1) # color palette used for bitmap2 (one color) palette2[0] = 0x0000FF -bitmap2 = displayio.Bitmap(chartWidth * 2, chartHeight * 2, 1) # create bitmap2 -tileGrid2 = displayio.TileGrid( +bitmap2 = displayio.Bitmap(chart_width * 2, chart_height * 2, 1) # create bitmap2 +tilegrid2 = displayio.TileGrid( bitmap2, pixel_shader=palette2, x=150, y=10 ) # Add bitmap2 to tilegrid2 -mySparkline2 = Sparkline( - width=chartWidth * 2, - height=chartHeight * 2, +sparkline2 = Sparkline( + width=chart_width * 2, + height=chart_height * 2, max_items=10, - yMin=0, - yMax=1, + y_min=0, + y_max=1, x=150, y=10, color=0xFF00FF, @@ -146,25 +152,25 @@ # Setup the third bitmap and third sparkline -# mySparkline3 contains a maximum of 10 items -# since yMin and yMax are not specified, mySparkline3 uses autoranging for both +# sparkline3 contains a maximum of 10 items +# since y_min and y_max are not specified, sparkline3 uses autoranging for both # the top and bottom of the y-axis. -# Note1: Any unspecified edge limit (yMin or yMax) will autorange that edge based +# Note1: Any unspecified edge limit (y_min or y_max) will autorange that edge based # on the data in the list. -# Note2: You can read back the value of the y-axis limits by using -# mySparkline3.yBottom or mySparkline3.yTop +# Note2: You can read back the current value of the y-axis limits by using +# sparkline3.y_bottom or sparkline3.y_top palette3 = displayio.Palette(1) # color palette used for bitmap (one color) palette3[0] = 0x11FF44 -bitmap3 = displayio.Bitmap(DISPLAY_WIDTH - 30, chartHeight * 2, 1) # create bitmap3 -tileGrid3 = displayio.TileGrid( +bitmap3 = displayio.Bitmap(DISPLAY_WIDTH - 30, chart_height * 2, 1) # create bitmap3 +tilegrid3 = displayio.TileGrid( bitmap3, pixel_shader=palette3, x=0, y=120 ) # Add bitmap3 to tilegrid3 -mySparkline3 = Sparkline( +sparkline3 = Sparkline( width=DISPLAY_WIDTH - 30, - height=chartHeight * 2, + height=chart_height * 2, max_items=10, x=0, y=120, @@ -172,47 +178,47 @@ ) # Initialize the y-axis labels for mySparkline3 with no text -textLabel3a = label.Label( +text_label3a = label.Label( font=font, text="", color=0x11FF44, max_glyphs=20 -) # yTop label -textLabel3a.anchor_point = (0, 0.5) # set the anchorpoint -textLabel3a.anchored_position = ( - mySparkline3.width, +) # y_top label +text_label3a.anchor_point = (0, 0.5) # set the anchorpoint +text_label3a.anchored_position = ( + sparkline3.width, 120, ) # set the text anchored position to the upper right of the graph -textLabel3b = label.Label( +text_label3b = label.Label( font=font, text="", color=0x11FF44, max_glyphs=20 -) # yTop label -textLabel3b.anchor_point = (0, 0.5) # set the anchorpoint -textLabel3b.anchored_position = ( - mySparkline3.width, - 120 + mySparkline3.height, +) # y_bottom label +text_label3b.anchor_point = (0, 0.5) # set the anchorpoint +text_label3b.anchored_position = ( + sparkline3.width, + 120 + sparkline3.height, ) # set the text anchored position to the upper right of the graph # Create a group to hold the three bitmap TileGrids and the three sparklines and -# append them into the group (myGroup) +# append them into the group (my_group) # # Note: In cases where display elements will overlap, then the order the elements # are added to the group will set which is on top. Latter elements are displayed # on top of former elemtns. -myGroup = displayio.Group(max_size=20) +my_group = displayio.Group(max_size=20) -myGroup.append(mySparkline1) -myGroup.append(textLabel1a) -myGroup.append(textLabel1b) +my_group.append(sparkline1) +my_group.append(text_label1a) +my_group.append(text_label1b) -myGroup.append(tileGrid2) -myGroup.append(mySparkline2) +my_group.append(tilegrid2) +my_group.append(sparkline2) -myGroup.append(tileGrid3) -myGroup.append(mySparkline3) -myGroup.append(textLabel3a) -myGroup.append(textLabel3b) +my_group.append(tilegrid3) +my_group.append(sparkline3) +my_group.append(text_label3a) +my_group.append(text_label3b) -# Set the display to show myGroup that contains all the bitmap TileGrids and +# Set the display to show my_group that contains all the bitmap TileGrids and # sparklines -display.show(myGroup) +display.show(my_group) i = 0 # This is a counter for changing the random values for mySparkline3 @@ -224,18 +230,18 @@ display.auto_refresh = False # add_value: add a new value to a sparkline - # Note: The y-range for mySparkline1 is set to -1 to 1.25, so all these random + # Note: The y-range for sparkline1 is set to -1 to 1.25, so all these random # values (between 0 and 1) will fit within the visible range of this sparkline - mySparkline1.add_value(random.uniform(0, 1)) + sparkline1.add_value(random.uniform(0, 1)) - # Note: For mySparkline2, the y-axis range is set from 0 to 1. + # Note: For sparkline2, the y-axis range is set from 0 to 1. # With the random values set between -1 and +2, the values will sometimes # be out of the y-range. This example shows how the fixed y-range (0 to 1) # will "clip" values (it will not display them) that are above or below the # y-range. - mySparkline2.add_value(random.uniform(-1, 2)) + sparkline2.add_value(random.uniform(-1, 2)) - # mySparkline3 is set autoranging for the top and bottom of the Y-axis + # sparkline3 is set autoranging for both the top and bottom of the Y-axis # In this example, for 15 values, this adds points in the range from 0 to 1. # Then, for the next 15 values, it adds points in the range of 0 to 10. @@ -245,11 +251,11 @@ # An exercise for the reader: You can set only one or the other sparkline axis # to autoranging by setting its value to None. if i < 15: - mySparkline3.add_value(random.uniform(0, 1)) + sparkline3.add_value(random.uniform(0, 1)) else: - mySparkline3.add_value(random.uniform(0, 10)) - textLabel3a.text = str(mySparkline3.yTop) - textLabel3b.text = str(mySparkline3.yBottom) + sparkline3.add_value(random.uniform(0, 10)) + text_label3a.text = str(sparkline3.y_top) + text_label3b.text = str(sparkline3.y_bottom) i += 1 # increment the counter if i > 30: # After 30 times through the loop, reset the counter i = 0 From 38cd21b7bac55601ba5e51c7a1b71ceae20a2226 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 13:36:12 -0500 Subject: [PATCH 16/17] deleted one more dispable=invalid-name --- adafruit_display_shapes/sparkline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index a98476d..99d2f93 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -120,7 +120,7 @@ def _plotline(self, x_1, last_value, x_2, value, y_bottom, y_top): y_1 = int(self.height * (y_top - last_value) / (y_top - y_bottom)) self.append(Line(x_1, y_1, x_2, y_2, self.color)) # plot the line - # pylint: disable=invalid-name, too-many-branches, too-many-nested-blocks + # pylint: disable= too-many-branches, too-many-nested-blocks def update(self): """Update the drawing of the sparkline From 7ddf5011ef01f9861d44b800fed50b6fdf88d6e3 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 22 Jul 2020 17:20:02 -0500 Subject: [PATCH 17/17] Updated _triple to define DISPLAY_WIDTH for pyPortal else statement --- examples/display_shapes_sparkline_triple.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/display_shapes_sparkline_triple.py b/examples/display_shapes_sparkline_triple.py index af975c8..f58a99d 100755 --- a/examples/display_shapes_sparkline_triple.py +++ b/examples/display_shapes_sparkline_triple.py @@ -84,6 +84,7 @@ else: # built-in display display = board.DISPLAY + DISPLAY_WIDTH = board.DISPLAY.width ########################################## # Create background bitmaps and sparklines