Time for action – using Matplotlib in Pygame

In this recipe we will take the position coordinates of the previous tutorial and make a graph from them. Perform the following steps to do so:

  1. Using a noninteractive backend: In order to integrate Matplotlib with Pygame we need to use a noninteractive backend, otherwise Matplotlib will present us with a GUI window by default. We will import the main Matplotlib module and call the use function. This function has to be called immediately after importing the main Matplotlib module and before other Matplotlib modules are imported.
    import matplotlib as mpl
        
    mpl.use("Agg")
  2. Noninteractive plots can be drawn on a Matplotlib canvas. Creating this canvas requires imports, creating a figure and a subplot. We will specify the figure to be 3 x 3 inches large. More details can be found at the end of this section.
    import matplotlib.pyplot as plt
    import matplotlib.backends.backend_agg as agg
    
    fig = plt.figure(figsize=[3, 3])
    ax = fig.add_subplot(111)
    canvas = agg.FigureCanvasAgg(fig)
  3. In noninteractive mode, plotting data is a bit more complicated than in the default mode. Since we need to plot repeatedly, it makes sense to organize the plotting code in a function. The plot is eventually drawn on the canvas. The canvas adds a bit of complexity to our setup. At the end of this example you can find a more detailed explanation of the functions.
    def plot(data):
        ax.plot(data)
        canvas.draw()
        renderer = canvas.get_renderer()
    
        raw_data = renderer.tostring_rgb()
        size = canvas.get_width_height()
    
        return pygame.image.fromstring(raw_data, size, "RGB")

    The following screenshot shows the animation in action. You can also view a screencast on YouTube at https://www.youtube.com/watch?v=t6qTeXxtnl4.

    Time for action – using Matplotlib in Pygame
  4. We get the following code after the changes:
    import pygame, sys
    from pygame.locals import *
    import numpy as np
    import matplotlib as mpl
    
    mpl.use("Agg")
    
    import matplotlib.pyplot as plt
    import matplotlib.backends.backend_agg as agg
    
    fig = plt.figure(figsize=[3, 3])
    ax = fig.add_subplot(111)
    canvas = agg.FigureCanvasAgg(fig)
    
    def plot(data):
        ax.plot(data)
        canvas.draw()
        renderer = canvas.get_renderer()
    
        raw_data = renderer.tostring_rgb()
        size = canvas.get_width_height()
    
        return pygame.image.fromstring(raw_data, size, "RGB")
    
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode((400, 400))
    
    pygame.display.set_caption('Animating Objects')
    img = pygame.image.load('head.jpg')
    
    steps = np.linspace(20, 360, 40).astype(int)
    right = np.zeros((2, len(steps)))
    down = np.zeros((2, len(steps)))
    left = np.zeros((2, len(steps)))
    up = np.zeros((2, len(steps)))
    
    right[0] = steps
    right[1] = 20
    
    down[0] = 360
    down[1] = steps
    
    left[0] = steps[::-1]
    left[1] = 360
    
    up[0] = 20
    up[1] = steps[::-1]
    
    pos = np.concatenate((right.T, down.T, left.T, up.T))
    i = 0
    history = np.array([])
    surf = plot(history)
    
    while True: 
        # Erase screen
        screen.fill((255, 255, 255))
    
        if i >= len(pos):
          i = 0
          surf = plot(history)
    
        screen.blit(img, pos[i])
        history = np.append(history, pos[i])
        screen.blit(surf, (100, 100))
    
        i += 1
    
        for event in pygame.event.get():
          if event.type == QUIT:
             pygame.quit()
             sys.exit()
    
        pygame.display.update()
        clock.tick(30)

What just happened?

The plotting-related functions are explained in the following table:

Function

Description

mpl.use("Agg")

This specifies the use of the noninteractive backend.

plt.figure(figsize=[3, 3])

This creates a figure of 3 x 3 inches.

agg.FigureCanvasAgg(fig)

This creates a canvas in noninteractive mode.

canvas.draw()

This draws on the canvas.

canvas.get_renderer()

This gets a renderer for the canvas.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.129.100