5 Best Ways to Draw Multiple Figures in Parallel in Python with Matplotlib

πŸ’‘ Problem Formulation: When handling complex data analyses, data scientists and developers often need to visualize different datasets or different aspects of the same dataset simultaneously. Utilizing Python with Matplotlib, one may require generating multiple plots in a single command execution efficiently. Imagine you have several sets of data and want to visualize each in a separate figure window, without blocking the execution to show one and then proceed to the next. This article describes five methods to do just that.

Method 1: Using matplotlib.pyplot Subplots

This method involves the use of matplotlib.pyplot’s subplot function. This function is highly effective when dealing with multiple figures that share a common axis label or title. It facilitates the creation of a grid of subplots within a single figure window where each subplot can act as an independent plot.

Here’s an example:

import matplotlib.pyplot as plt

# Create a figure with a grid of subplots
fig, axs = plt.subplots(2, 2) # Creates a 2x2 grid

# Plot different data sets on each subplot
axs[0, 0].plot(x1, y1)
axs[0, 1].plot(x2, y2)
axs[1, 0].plot(x3, y3)
axs[1, 1].plot(x4, y4)

# Show the plot
plt.show()

The output will be one window containing a 2×2 grid of individual plots.

This code creates a single figure with a 2×2 grid of subplots, each of which can hold a separate plot. By referencing the axs array, we can easily place our data into the desired subplot location. This grid system is particularly useful for comparative analysis or when several plots share related contexts.

Method 2: Creating Multiple Figures

By using the plt.figure() command, we can spawn multiple separate figure windows that can be filled with individual plots. This method is useful if the figures are unrelated or if you want to view them side by side rather than in a grid format.

Here’s an example:

import matplotlib.pyplot as plt

# First figure
plt.figure()
plt.plot(x1, y1)

# Second figure
plt.figure()
plt.plot(x2, y2)

# Show all figures
plt.show()

The output will be two separate windows, each displaying a distinct plot.

In the example, we first create a plot and then a new figure is initiated without affecting the previous one. Different datasets or plot types can be visualized separately, allowing for a straightforward comparison. It’s a versatile approach to have multiple figures with maximal flexibility.

Method 3: Using Threads for True Parallelization

If true parallel processing and drawing is required, threading can allow separate figures to be rendered simultaneously. However, caution is required when using threads with GUIs like Matplotlib, due to potential conflicts with threading models and rendering engines.

Here’s an example:

import matplotlib.pyplot as plt
import threading

def plot_data(x, y):
    plt.figure()
    plt.plot(x, y)
    plt.show()

# Create threads
thread1 = threading.Thread(target=plot_data, args=(x1, y1))
thread2 = threading.Thread(target=plot_data, args=(x2, y2))

# Start threads
thread1.start()
thread2.start()

# Join threads to wait for both to finish
thread1.join()
thread2.join()

The output will be two plots appearing nearly simultaneously in different windows.

The code snippet encapsulates the plot operation within a function and then employs Python’s threading library to execute multiple instances of this function concurrently. This is closer to true parallel plot rendering, allowing more responsiveness especially when dealing with computationally heavy plotting tasks.

Method 4: Asynchronous Plotting with Asyncio

Using Python’s asyncio library, we can create asynchronous plot functions that can be awaited and thus potentially allow other operations to occur in the meantimeβ€” a very useful method when integrating plotting into an asynchronous application.

Here’s an example:

import asyncio
import matplotlib.pyplot as plt

async def async_plot(x, y):
    plt.figure()
    plt.plot(x, y)
    plt.show()

# Event loop
loop = asyncio.get_event_loop()
tasks = [async_plot(x1, y1), async_plot(x2, y2)]
wait_tasks = asyncio.wait(tasks)
loop.run_until_complete(wait_tasks)
loop.close()

Similar to the threading output, this will display plots seemingly at the same time, but managed through an async loop.

Whilst matplotlib does not inherently support asyncio, this code snippet demonstrates a pattern for integrating it into an async loop, showcasing how multiple plots can be displayed while a program continues to run other asynchronous tasks, optimizing for responsiveness and efficiency.

Bonus One-Liner Method 5: Using pyplot‘s pause Function

A one-liner method that can be used effectively for quickly iterating through different plots is utilizing pause function from matplotlib.pyplot, which draws a plot, pauses execution for the specified amount of time and allows to quickly switch to the next plot.

Here’s an example:

import matplotlib.pyplot as plt

for (x, y) in data_sets:
    plt.figure()
    plt.plot(x, y)
    plt.pause(0.1) # pause for a fraction of a second
plt.show()

The output is a rapid succession of plots appearing one after the other.

This is a quick and easy way to iterate through multiple datasets and view them in separate figures with minimal delay between them. It’s great for inspecting a series of plots quickly but is not ideal for complex or interactive tasks.

Summary/Discussion

  • Method 1: Subplots. Useful for related data, provides a tidy grid layout. Comparisons are easier, but complex arrangements can become cumbersome.
  • Method 2: Creating Multiple Figures. Allows maximal flexibility with separate windows. Ideal for unrelated data visualizations, uses more resources.
  • Method 3: Using Threads. Offers true parallel rendering; however, it can cause thread-related issues in GUI applications.
  • Method 4: Asyncio Plotting. Integrates well with asynchronous applications; however, compatibility with Matplotlib can be tricky.
  • Method 5: Pause Function. Best for quick data inspections, not suitable for in-depth analysis or interactivity.