2D visualization of data using Pygame in Python

Pygame is primarily a library for game development, but it can also be effectively used for 2D data visualization. Its ability to handle graphics, animations, and real-time updates makes it suitable for visualizing sensor data, simulations, and dynamic datasets.

Pygame for Data Visualization

  • Real-time rendering – Ideal for continuously updating datasets like LiDAR, sensor readings, or robotics data.
  • Custom graphics – You can create unique visualization styles without being restricted to standard charting tools.
  • Event handling – Useful for interactive visualizations where user input affects the displayed data.
  • Animations – Can be used to animate data changes over time.

Key Concepts for Visualization in Pygame

1. Displaying Data Points

  • Use pygame.draw.circle() or pygame.draw.rect() to represent points.
  • Example: Visualizing LiDAR sensor readings as a point cloud.

2. Drawing Lines and Graphs

  • pygame.draw.line() to connect data points for line graphs.
  • pygame.draw.polygon() to create filled areas for a heatmap-like effect.

3. Handling Real-time Data Streams

  • Use pygame.time.Clock() to control frame rate.
  • Fetch data from external sources like a sensor or file.
  • Update the display dynamically.

4. Color Mapping

  • Use RGB values to represent different data intensities.
  • Example: Darker shades for higher values in heatmaps.

5. Interactive Elements

  • Use pygame.MOUSEBUTTONDOWN or pygame.KEYDOWN events for zooming, panning, or toggling display options.

Applications in Robotics and IoT

  • LiDAR Data Visualization: Display real-time LiDAR scans in a 2D environment.
  • Sensor Readings: Represent temperature, humidity, or distance measurements dynamically.
  • Path Planning: Show robot movements and obstacles in an environment.
  • Heatmaps: Visualize intensity variations over a grid.

Example code for visualizing data from Lidar in Pygame:

code:

import pygame, math, serial, numpy

pygame.init()

#constant based on lidar resolution

LIDAR_RESOLUTION = 240

#lidar resolution divided by 4 to simplify the visualization

VISUALIZATION_RESOLUTION = 240

distances_list = []

first_run = True

def GetDataFromArduino(line):

  global distances_list, first_run

  #[:-3] get rid of end of line sign and additional comma separator that is sent from arduino

  data = line[:-3]

  print(data)

  d_list= data.split(“,”)

  return d_list

def GenerateLinePositions(numberOfLines):

  angle = 360/numberOfLines

  lines = []

  for x in range(numberOfLines):

    lines.append([300 * math.cos((x+1)*angle/180 * math.pi), 300 * math.sin((x+1)*angle/180 * math.pi)])

  return lines

line_positions = GenerateLinePositions(VISUALIZATION_RESOLUTION)

# Set up the drawing window

screen = pygame.display.set_mode([800, 800])

sysfont = pygame.font.get_default_font()

font1 = pygame.font.SysFont(sysfont, 72)

file1 = open(‘D:githubMachine-Learning-Robotdatadata7.txt’, ‘r’)

Lines = file1.readlines()

for line in Lines:

  distances = GetDataFromArduino(line)

  print(len(distances))

  if(len(distances) == LIDAR_RESOLUTION):

    # Did the user click the window close button?

    for event in pygame.event.get():

      if event.type == pygame.QUIT:

        running = False

       

   

    # Fill the background with white

    screen.fill((250, 250, 250))

   

    for x in range(VISUALIZATION_RESOLUTION):

      if distances[x] == 0:

        distances[x] = 20

      a = int(float(distances[x]))/2000

      if x in [136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 176, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223]:

        pygame.draw.circle(screen, (255,0,0), (line_positions[x][0]*a+400, line_positions[x][1]*a+400), 3)

      else:

        pygame.draw.circle(screen, (0,0,0), (line_positions[x][0]*a+400, line_positions[x][1]*a+400), 2)

       

       

    pygame.draw.circle(screen, (252, 132, 3), (400, 400), 12)

    # Flip the display

    pygame.display.flip()

    pygame.time.wait(200)

pygame.quit()

output:

Leave a comment

Your email address will not be published. Required fields are marked *