Matplotlib 简明教程

Matplotlib - Multiprocessing

Multiprocessing 是一种用于并发执行多个进程的技术,利用了多核处理器。在 Python 中,multiprocessing 模块提供了一种便捷的方法来创建和管理并行进程。这对于可以并行化的任务很有用,例如生成图表、运行模拟或对大型数据集执行计算。

Multiprocessing is a technique used to execute multiple processes concurrently, taking advantage of multi-core processors. In Python, the multiprocessing module provides a convenient way to create and manage parallel processes. This is useful for tasks that can be parallelized, such as generating plots, running simulations, or performing computations on large datasets.

Multiprocessing in Matplotlib

Matplotlib 传统上以单线程方式使用,将其与多处理库结合使用可以并行创建图表。在处理大量图表或计算密集型任务时,这非常有用。

Matplotlib is traditionally used in a single-threaded manner, combining it with the multiprocessing library allows for the creation of plots in parallel. This can be useful when dealing with a large number of plots or computationally intensive tasks.

Creating Multiple Matplotlib Plots

按顺序创建多个图表会导致执行速度较慢,尤其是在处理大量图表时。在这种情况中,使用多处理技术可以通过允许并发创建多个图表来显著提高性能。

Creating multiple plots sequentially can lead to a slower execution, especially when dealing with a large number of plots. In such cases, using the multiprocessing technique can significantly improve performance by allowing the creation of multiple plots concurrently.

Example

让我们看一个基本示例,演示如何使用多处理并行创建多个 Matplotlib 图表。

Let’s see a basic example that demonstrates how to create multiple Matplotlib plots in parallel using multiprocessing.

import matplotlib.pyplot as plt
import numpy as np
import multiprocessing

def plot(datax, datay, name):
   x = datax
   y = datay**2
   plt.scatter(x, y, label=name)
   plt.legend()
   plt.show()

def multiP():
   for i in range(4):
      p = multiprocessing.Process(target=plot, args=(i, i, i))
      p.start()

if __name__ == "__main__":
   input('Press Enter to start parallel plotting...')
   multiP()

执行上述程序后,将并行创建 4 个 matplotlib 图表,请参阅下面的视频以获取参考 −

On executing the above program, 4 matplotlib plots are created in parallel see the video below for reference −

multiprocessing ex1

Saving Multiple Matplotlib Figures

并行保存多个 Matplotlib 图形是多处理可以发挥优势的另一个场景。

Saving multiple Matplotlib figures concurrently is another scenario where multiprocessing can be advantageous.

Example 1

这是一个使用多处理并行保存多个 Matplotlib 图形的示例。

Here is an example that uses multiprocessing to save multiple Matplotlib figures concurrently.

import matplotlib.pyplot as plt
import numpy.random as random
from multiprocessing import Pool

def do_plot(number):
   fig = plt.figure(number)

   a = random.sample(1000)
   b = random.sample(1000)

   # generate random data
   plt.scatter(a, b)

   plt.savefig("%03d.jpg" % (number,))
   plt.close()

   print(f"Image {number} saved successfully...")

if __name__ == '__main__':
   pool = Pool()
   pool.map(do_plot, range(1, 5))

执行上述代码,我们将得到以下输出 −

On executing the above code we will get the following output −

Image 1 saved successfully...
Image 2 saved successfully...
Image 3 saved successfully...
Image 4 saved successfully...

如果您导航到保存图表的目录,您将能够看到 ved 001.jpg、002.jpg、003.jpg 和 004.jpg 图像,如下所示 −

If you navigate to the directory where the plots were saved, you will be able to observe the ved 001.jpg, 002.jpg, 003.jpg, and 004.jpg images as shown below −

multiprocessing ex2

Example 2

这是另一个演示如何使用多处理在一个进程中生成数据并在另一个进程中使用 Matplotlib 绘图的示例。

Here is another example that demonstrates how to use multiprocessing to generate data in one process and plot it in another using Matplotlib.

import multiprocessing as mp
import time
import matplotlib.pyplot as plt
import numpy as np

# Fixing random state for reproducibility
np.random.seed(19680801)

class ProcessPlotter:
   def __init__(self):
      self.x = []
      self.y = []

   def terminate(self):
      plt.close('all')

   def call_back(self):
      while self.pipe.poll():
         command = self.pipe.recv()
         if command is None:
            self.terminate()
            return False
         else:
            self.x.append(command[0])
            self.y.append(command[1])
            self.ax.plot(self.x, self.y, 'ro')
      self.fig.canvas.draw()
      return True

   def __call__(self, pipe):
      print('Starting plotter...')
      self.pipe = pipe
      self.fig, self.ax = plt.subplots()
      timer = self.fig.canvas.new_timer(interval=1000)
      timer.add_callback(self.call_back)
      timer.start()
      print('...done')
      plt.show()

class NBPlot:
   def __init__(self):
      self.plot_pipe, plotter_pipe = mp.Pipe()
      self.plotter = ProcessPlotter()
      self.plot_process = mp.Process(
         target=self.plotter, args=(plotter_pipe,), daemon=True)
      self.plot_process.start()

   def plot(self, finished=False):
      send = self.plot_pipe.send
      if finished:
         send(None)
      else:
         data = np.random.random(2)
         send(data)

# Main function for the integrated code
def main_with_multiprocessing():
   pl = NBPlot()
   for _ in range(10):
      pl.plot()
      time.sleep(0.5)
   pl.plot(finished=True)

if __name__ == '__main__':
   if plt.get_backend() == "MacOSX":
      mp.set_start_method("forkserver")
   input('Press Enter to start integrated example...')
   main_with_multiprocessing()

执行上述程序后,将使用随机数据生成 matplotlib 图表,请参阅下面的视频以获取参考 −

On executing the above program, will generate the matplotlib plots with random data see the video below for reference −

multiprocessing ex3