1

I have a stream of input data from multiple "channels" and I want to represent each channel's data stream within a section of the screen using pygame.

The streaming data is captured in a pandas data.frame and summarized every few seconds. Right now I've prototyped this using only the first channel of data and fullscreen mode in pygame (i.e., scr = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)).

The way I'm trying to divide up the screen is a lot like this but instead of having a fixed number of sub-screens to create, I'm hoping to reference the number of columns in the pandas data.frame to divide up the screen programmatically.

Should this be done using Surface and some sort of loop? Just looking for some guidance as this type of programming is new to me. I've seen something vaguely similar with geographic data (like this) but the context of working with displays and pygame is enough to make me a bit uncertain.

Hack-R
  • 22,422
  • 14
  • 75
  • 131

1 Answers1

2

I would indeed work with pygame.Surfaces and a loop.

I took a primer on pygame (my go to is: https://realpython.com/pygame-a-primer/) and added how I would implement multiple sub_screens (or surfs in my script below). I hope my code and comments are clear enough to get what's going on, otherwise just ask!

For now I just fill the sub-screens with random colors, but you can blit anything you want on the sub-screens (in or outside the while-loop), as they are just good old pygame.Surfaces.

import pygame
import random

# init pygame
pygame.init()

# set up parameters
n_rows = 5
n_cols = 3

screen_width = 800
screen_height = 500

# Create a dict with the row and column as key,
# and a tuple containing a Surface and its topleft coordinate as value
surf_width = round(screen_width / n_cols)
surf_height = round(screen_height / n_rows)

surfaces_dct = {}
for row in range(n_rows):
    for col in range(n_cols):

        # create a surface with given size
        surf = pygame.Surface(size=(surf_width, surf_height))
        # get its top left coordinate
        top_left = (col*surf_width, row*surf_height)

        # put it in the dict as a tuple
        surfaces_dct[(row, col)] = (surf, top_left)


# Here you can blit anything to each surface/sub-screen (defined by it's row and column):
for key, value in surfaces_dct.items():
    # unpack the key, value pairs
    (row, col) = key
    (surf, top_left) = value
    
    # I just fill each surface with a random color for demonstration
    (r, g, b) = [random.randint(0, 255) for i in range(3)]
    surf.fill((r, g, b))


# Set up the drawing window
screen = pygame.display.set_mode([screen_width, screen_height])

# Run until the user asks to quit
running = True
while running:

    # Did the user click the window close button?
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # You can also run this for-loop here, inside the main while-loop
    # to dynamically change what's on each surf
    # as you see you can also unpack the key and value like this
    for (row, col), (surf, top_left) in surfaces_dct.items():
        # I'll leave it blank here
        pass


    # Finally place(/blit) the surfaces on the screen given
    screen.blits(list(surfaces_dct.values()))

    #### the above is the same as doing:
    # for surf, top_left in surfaces_dct.values():
    #     screen.blit(surf, top_left)

    # Update the display
    pygame.display.update()
Andre
  • 760
  • 3
  • 13