matplotlib动画需要大量的时间来运行

发布于 2025-01-22 22:59:39 字数 13730 浏览 1 评论 0原文

我正在使用Animation.funcanimation进行相当简单的matplotlib动画,并且运行时间很长。在11秒长的视频中,每帧约0.81和220帧的180帧。我已经结合了标准的性能改进,即在动画循环中没有创建艺术家对象并返回所有更新的艺术家对象,以便可以完成闪光,但都没有对性能产生重大影响。我已经计时了newFrame函数的内容,并且运行约为0.6ms。我的代码在下面。

还有其他建议如何加快它或并行化?

编辑:看来性能问题与子图主要有关。减少子图的数量会大大减少执行时间。并不是一个很好的解决方案,但值得注意的

编辑2:评论axsArray [a,b] .minorticks_on()将性能翻倍至〜0.4 s每一帧。这使得性能更符合我基于Matplotlib动画的先前经验的期望,尽管对于简单的情节来说仍然非常慢。

#!/usr/bin/env python3

from timeit import default_timer

import matplotlib
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import os
import sys

matplotlib.use("Agg")

plt.close('all')
start = default_timer()


# ==============================================================================
def main():
    # ==========================================================================
    # Settings
    # ==========================================================================
    # Check for CLI arguments
    if len(sys.argv) == 2:
        cliFPS = int(sys.argv[1])
    elif len(sys.argv) > 2:
        raise TypeError(f"Too many ({len(sys.argv)}) command line arguments given")

    # Data settings
    loadPath = ''
    yPos     = 16  # y position of the x line to load
    zPos     = 16  # z position of the x line to load

    # Plot Settings
    supTitleText  = "Time Evolution of Initial Conditions"
    densityColor  = 'blue'                      # color of the density plot
    velocityColor = 'purple'                    # color of the velocity plots
    magneticColor = 'tab:orange'                # color of the magnetic field plots
    pressureColor = 'green'                     # color of the pressure plot
    ieColor       = 'red'                       # color of the specific internal energy plot
    linestyle     = '-'                         # The line style
    linewidth     = 0.5                         # How wide to make the lines
    marker        = "."                         # Marker kind for points
    markersize    = 3                           # Size of the marker
    figSizeScale  = 2.                          # Scaling factor for the figure size
    figHeight     = 4.8 * figSizeScale          # height of the plot in inches, default is 4.8
    figWidth      = 7.0 * figSizeScale          # width of the plot in inches, default is 6.4
    padPercent    = 0.05                        # How many percent larger the limits should be than the data

    # Video Settings
    OutFile       = "mvp.mp4"                   # Output filename
    Duration      = 10.                         # How long the video is in seconds
    dpi           = 150                         # Dots per inch
    index         = 0                           # Initialize index
    initIndex     = 0                           # Index for init frames
    fps           = cliFPS if ("cliFPS" in locals()) else 20  # Framerate
    FrameTime     = (1./fps) * 1000             # Frametime in milliseconds
    totFrames     = int(fps * Duration)         # Total number of frames (floor)
    # ==========================================================================
    # End settings
    # ==========================================================================

    # Load data
    (densityData, velocityXData, velocityYData, velocityZData, pressureData,
     ieData, magneticXData, magneticYData, magneticZData, positions,
     timeStepNum, dims, physicalSize) = loadData(loadPath, yPos, zPos)

    # Compute which time steps to plot
    if timeStepNum.size >= totFrames:
        floatSamples    = np.arange(0, timeStepNum.size, timeStepNum.size/totFrames)
        timeStepSamples = np.asarray(np.floor(floatSamples), dtype="int")
    else:  # if the number of simulation steps is less than the total number of frames
        totFrames = timeStepNum.size
        fps       = np.ceil(totFrames/Duration)
        FrameTime = (1./fps) * 1000
        timeStepSamples = np.arange(0, timeStepNum.size, 1, dtype="int")

    # Insert the initial second of the initial conditions
    timeStepSamples = np.insert(timeStepSamples, 0, [0]*fps)

    # Get the plot limits
    densityLowLim, densityHighLim     = computeLimit(densityData, padPercent)
    ieLowLim, ieHighLim               = computeLimit(ieData, padPercent)
    pressureLowLim, pressureHighLim   = computeLimit(pressureData, padPercent)
    velocityXLowLim, velocityXHighLim = computeLimit(velocityXData, padPercent)
    velocityYLowLim, velocityYHighLim = computeLimit(velocityYData, padPercent)
    velocityZLowLim, velocityZHighLim = computeLimit(velocityXData, padPercent)
    magneticXLowLim, magneticXHighLim = computeLimit(magneticXData, padPercent)
    magneticYLowLim, magneticYHighLim = computeLimit(magneticYData, padPercent)
    magneticZLowLim, magneticZHighLim = computeLimit(magneticZData, padPercent)

    # Set up plots
    # Create 9 subplots
    fig, subPlot = plt.subplots(3, 3, figsize = (figWidth, figHeight))

    # Super Title
    titleText = fig.suptitle(supTitleText)

    # Shared x-label
    subPlot[2,0].set_xlabel("Position")
    subPlot[2,1].set_xlabel("Position")
    subPlot[2,2].set_xlabel("Position")

    # Set values for the subplots
    densityPlot,   subPlot = setupSubPlots('Density',         densityLowLim,   densityHighLim,   positions, densityData,   linestyle, linewidth, marker, markersize, densityColor,  subPlot)
    pressurePlot,  subPlot = setupSubPlots('Pressure',        pressureLowLim,  pressureHighLim,  positions, pressureData,  linestyle, linewidth, marker, markersize, pressureColor, subPlot)
    iePlot,        subPlot = setupSubPlots('Internal Energy', ieLowLim,        ieHighLim,        positions, ieData,        linestyle, linewidth, marker, markersize, ieColor,       subPlot)
    velocityXPlot, subPlot = setupSubPlots('$V_x$',           velocityXLowLim, velocityXHighLim, positions, velocityXData, linestyle, linewidth, marker, markersize, velocityColor, subPlot)
    velocityYPlot, subPlot = setupSubPlots('$V_y$',           velocityYLowLim, velocityYHighLim, positions, velocityYData, linestyle, linewidth, marker, markersize, velocityColor, subPlot)
    velocityZPlot, subPlot = setupSubPlots('$V_z$',           velocityZLowLim, velocityZHighLim, positions, velocityZData, linestyle, linewidth, marker, markersize, velocityColor, subPlot)
    magneticXPlot, subPlot = setupSubPlots('$B_x$',           magneticXLowLim, magneticXHighLim, positions, magneticXData, linestyle, linewidth, marker, markersize, magneticColor, subPlot)
    magneticYPlot, subPlot = setupSubPlots('$B_y$',           magneticYLowLim, magneticZHighLim, positions, magneticYData, linestyle, linewidth, marker, markersize, magneticColor, subPlot)
    magneticZPlot, subPlot = setupSubPlots('$B_z$',           magneticZLowLim, magneticZHighLim, positions, magneticZData, linestyle, linewidth, marker, markersize, magneticColor, subPlot)

    # Layout
    plt.tight_layout()
    fig.subplots_adjust(top=0.88)

    # Generate animation
    simulation = animation.FuncAnimation(fig,
                                         newFrame,
                                         fargs = (fig, supTitleText, densityPlot, pressurePlot, iePlot,
                                                  velocityXPlot, velocityYPlot, velocityZPlot,
                                                  magneticXPlot, magneticYPlot, magneticZPlot,
                                                  densityData, pressureData, ieData,
                                                  velocityXData, velocityYData, velocityZData,
                                                  magneticXData, magneticYData, magneticZData,
                                                  timeStepSamples, titleText),
                                         blit = True,
                                         frames = timeStepSamples,
                                         interval = FrameTime,
                                         repeat = False)

    FFwriter = animation.FFMpegWriter(bitrate=1000,
                                      fps=fps,
                                      codec='libx264',
                                      extra_args=['-crf','28','-preset','ultrafast','-pix_fmt','yuv420p'])
    simulation.save(filename=OutFile, writer = FFwriter)
    # simulation.save(filename=OutFile, fps=fps, dpi=dpi)
    print(f"\n\nAnimation complete. Framerate: {fps} fps, Total Number of Frames: {timeStepSamples.size}")
# ==============================================================================

# ==============================================================================
def loadData(path, yPos, zPos):

    numFiles = 870
    dims = [32, 32, 32]
    physicalSize = [1,1,1]

    np.random.random((numFiles, dims[0]))

    # Allocate Arrays
    densityData        = np.random.random((numFiles, dims[0]))
    velocityXData      = np.random.random((numFiles, dims[0]))
    velocityYData      = np.random.random((numFiles, dims[0]))
    velocityZData      = np.random.random((numFiles, dims[0]))
    pressureData       = np.random.random((numFiles, dims[0]))
    ieData             = np.random.random((numFiles, dims[0]))
    magneticXData      = np.random.random((numFiles, dims[0]))
    magneticYData      = np.random.random((numFiles, dims[0]))
    magneticZData      = np.random.random((numFiles, dims[0]))
    timeStepNum        = np.arange(0, numFiles, 1)
    positions          = np.linspace(0., 1, dims[0])

    return (densityData, velocityXData, velocityYData, velocityZData,
            pressureData, ieData, magneticXData, magneticYData, magneticZData,
            positions, timeStepNum, dims, physicalSize)
# ==============================================================================

# ==============================================================================
def setupSubPlots(fieldName, lowLim, highLim, positions, data, linestyle, linewidth, marker, markersize, color, axsArray):
    # Get the subplot coordinates to set
    if fieldName == 'Density':
        a, b = (0,0)
    elif fieldName == 'Pressure':
        a, b = (0,1)
    elif fieldName == 'Internal Energy':
        a, b = (0,2)
    elif fieldName == '$V_x$':
        a, b = (1,0)
    elif fieldName == '$V_y$':
        a, b = (1,1)
    elif fieldName == '$V_z$':
        a, b = (1,2)
    elif fieldName == '$B_x$':
        a, b = (2,0)
    elif fieldName == '$B_y$':
        a, b = (2,1)
    elif fieldName == '$B_z$':
        a, b = (2,2)
    else:
        raise ValueError('setSubPlots received invalid fieldName')

    # Set plot parameters
    axsArray[a,b].set_ylim(lowLim, highLim)
    axsArray[a,b].set_ylabel(fieldName)
    axsArray[a,b].minorticks_on()
    axsArray[a,b].grid(which = "both")

    # Set initial values
    returnPlot, = axsArray[a,b].plot(positions,
                                     data[0,:],
                                     linestyle  = linestyle,
                                     linewidth  = linewidth,
                                     marker     = marker,
                                     markersize = markersize,
                                     color      = color,
                                     label      = fieldName,
                                     animated   = True)

    return returnPlot, axsArray
# ==============================================================================

# ==============================================================================
def computeLimit(dataSet, padPercent):
    pad = np.max(np.abs([dataSet.min(), dataSet.max()])) * padPercent
    if pad == 0:
        # if the dataset doesn't exist or is zero return reasonable limits
        return -1, 1
    else:
        lowLim  = dataSet.min() - pad
        highLim = dataSet.max() + pad
        return lowLim, highLim
# ==============================================================================

# ==============================================================================
def newFrame(idx, fig, supTitleText, densityPlot, pressurePlot, iePlot,
             velocityXPlot, velocityYPlot, velocityZPlot,
             magneticXPlot, magneticYPlot, magneticZPlot,
             densityData, pressureData, ieData,
             velocityXData, velocityYData, velocityZData,
             magneticXData, magneticYData, magneticZData,
             timeStepSamples, titleText):
    titleText.set_text(f"{supTitleText} \n Time Step: {idx}")

    densityPlot  .set_ydata(densityData[idx,:])
    pressurePlot .set_ydata(pressureData[idx,:])
    iePlot       .set_ydata(ieData[idx,:])

    velocityXPlot.set_ydata(velocityXData[idx,:])
    velocityYPlot.set_ydata(velocityYData[idx,:])
    velocityZPlot.set_ydata(velocityZData[idx,:])

    magneticXPlot.set_ydata(magneticXData[idx,:])
    magneticYPlot.set_ydata(magneticYData[idx,:])
    magneticZPlot.set_ydata(magneticZData[idx,:])

    # Report progress
    if not hasattr(newFrame, "counter"):
        newFrame.counter = -1  # Accounts for first call which is performed before the animation starts
        print()

    if newFrame.counter >= 0:
        print(f'Animation is {100*(newFrame.counter/timeStepSamples.shape[0]):.1f}% complete', end='\r')

    newFrame.counter += 1

    # The return is required to make blit work
    return (titleText, densityPlot, pressurePlot, iePlot,
            velocityXPlot, velocityYPlot, velocityZPlot,
            magneticXPlot, magneticYPlot, magneticZPlot)
# ==============================================================================

main()

print(f'Time to execute: {round(default_timer()-start,2)} seconds')

I'm working on a fairly simple matplotlib animation using animation.FuncAnimation and it takes a very long time to run; about 0.81s per frame and 180s for the 220 frames in an 11 second long video. I've already incorporated the standard performance improvements, namely not creating Artist objects in the animation loop and returning all updated Artists objects so that bliting can be done but neither has had a significant impact on performance. I've timed the contents of the newFrame function and it only takes about 0.6ms to run. My code is below.

Any other suggestions how how to speed this up or parallelize it?

EDIT: It looks like the performance issues are largely to do with the subplots. Reducing the number of subplots reduces the execution time dramatically. Not really a great solution but noteworthy

EDIT 2: Commenting out axsArray[a,b].minorticks_on() doubles the performance to ~0.4s per frame. This brings performance more in line with what I expect based on previous experience with matplotlib animations, though still incredibly slow for a simple plot.

#!/usr/bin/env python3

from timeit import default_timer

import matplotlib
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import os
import sys

matplotlib.use("Agg")

plt.close('all')
start = default_timer()


# ==============================================================================
def main():
    # ==========================================================================
    # Settings
    # ==========================================================================
    # Check for CLI arguments
    if len(sys.argv) == 2:
        cliFPS = int(sys.argv[1])
    elif len(sys.argv) > 2:
        raise TypeError(f"Too many ({len(sys.argv)}) command line arguments given")

    # Data settings
    loadPath = ''
    yPos     = 16  # y position of the x line to load
    zPos     = 16  # z position of the x line to load

    # Plot Settings
    supTitleText  = "Time Evolution of Initial Conditions"
    densityColor  = 'blue'                      # color of the density plot
    velocityColor = 'purple'                    # color of the velocity plots
    magneticColor = 'tab:orange'                # color of the magnetic field plots
    pressureColor = 'green'                     # color of the pressure plot
    ieColor       = 'red'                       # color of the specific internal energy plot
    linestyle     = '-'                         # The line style
    linewidth     = 0.5                         # How wide to make the lines
    marker        = "."                         # Marker kind for points
    markersize    = 3                           # Size of the marker
    figSizeScale  = 2.                          # Scaling factor for the figure size
    figHeight     = 4.8 * figSizeScale          # height of the plot in inches, default is 4.8
    figWidth      = 7.0 * figSizeScale          # width of the plot in inches, default is 6.4
    padPercent    = 0.05                        # How many percent larger the limits should be than the data

    # Video Settings
    OutFile       = "mvp.mp4"                   # Output filename
    Duration      = 10.                         # How long the video is in seconds
    dpi           = 150                         # Dots per inch
    index         = 0                           # Initialize index
    initIndex     = 0                           # Index for init frames
    fps           = cliFPS if ("cliFPS" in locals()) else 20  # Framerate
    FrameTime     = (1./fps) * 1000             # Frametime in milliseconds
    totFrames     = int(fps * Duration)         # Total number of frames (floor)
    # ==========================================================================
    # End settings
    # ==========================================================================

    # Load data
    (densityData, velocityXData, velocityYData, velocityZData, pressureData,
     ieData, magneticXData, magneticYData, magneticZData, positions,
     timeStepNum, dims, physicalSize) = loadData(loadPath, yPos, zPos)

    # Compute which time steps to plot
    if timeStepNum.size >= totFrames:
        floatSamples    = np.arange(0, timeStepNum.size, timeStepNum.size/totFrames)
        timeStepSamples = np.asarray(np.floor(floatSamples), dtype="int")
    else:  # if the number of simulation steps is less than the total number of frames
        totFrames = timeStepNum.size
        fps       = np.ceil(totFrames/Duration)
        FrameTime = (1./fps) * 1000
        timeStepSamples = np.arange(0, timeStepNum.size, 1, dtype="int")

    # Insert the initial second of the initial conditions
    timeStepSamples = np.insert(timeStepSamples, 0, [0]*fps)

    # Get the plot limits
    densityLowLim, densityHighLim     = computeLimit(densityData, padPercent)
    ieLowLim, ieHighLim               = computeLimit(ieData, padPercent)
    pressureLowLim, pressureHighLim   = computeLimit(pressureData, padPercent)
    velocityXLowLim, velocityXHighLim = computeLimit(velocityXData, padPercent)
    velocityYLowLim, velocityYHighLim = computeLimit(velocityYData, padPercent)
    velocityZLowLim, velocityZHighLim = computeLimit(velocityXData, padPercent)
    magneticXLowLim, magneticXHighLim = computeLimit(magneticXData, padPercent)
    magneticYLowLim, magneticYHighLim = computeLimit(magneticYData, padPercent)
    magneticZLowLim, magneticZHighLim = computeLimit(magneticZData, padPercent)

    # Set up plots
    # Create 9 subplots
    fig, subPlot = plt.subplots(3, 3, figsize = (figWidth, figHeight))

    # Super Title
    titleText = fig.suptitle(supTitleText)

    # Shared x-label
    subPlot[2,0].set_xlabel("Position")
    subPlot[2,1].set_xlabel("Position")
    subPlot[2,2].set_xlabel("Position")

    # Set values for the subplots
    densityPlot,   subPlot = setupSubPlots('Density',         densityLowLim,   densityHighLim,   positions, densityData,   linestyle, linewidth, marker, markersize, densityColor,  subPlot)
    pressurePlot,  subPlot = setupSubPlots('Pressure',        pressureLowLim,  pressureHighLim,  positions, pressureData,  linestyle, linewidth, marker, markersize, pressureColor, subPlot)
    iePlot,        subPlot = setupSubPlots('Internal Energy', ieLowLim,        ieHighLim,        positions, ieData,        linestyle, linewidth, marker, markersize, ieColor,       subPlot)
    velocityXPlot, subPlot = setupSubPlots('$V_x
,           velocityXLowLim, velocityXHighLim, positions, velocityXData, linestyle, linewidth, marker, markersize, velocityColor, subPlot)
    velocityYPlot, subPlot = setupSubPlots('$V_y
,           velocityYLowLim, velocityYHighLim, positions, velocityYData, linestyle, linewidth, marker, markersize, velocityColor, subPlot)
    velocityZPlot, subPlot = setupSubPlots('$V_z
,           velocityZLowLim, velocityZHighLim, positions, velocityZData, linestyle, linewidth, marker, markersize, velocityColor, subPlot)
    magneticXPlot, subPlot = setupSubPlots('$B_x
,           magneticXLowLim, magneticXHighLim, positions, magneticXData, linestyle, linewidth, marker, markersize, magneticColor, subPlot)
    magneticYPlot, subPlot = setupSubPlots('$B_y
,           magneticYLowLim, magneticZHighLim, positions, magneticYData, linestyle, linewidth, marker, markersize, magneticColor, subPlot)
    magneticZPlot, subPlot = setupSubPlots('$B_z
,           magneticZLowLim, magneticZHighLim, positions, magneticZData, linestyle, linewidth, marker, markersize, magneticColor, subPlot)

    # Layout
    plt.tight_layout()
    fig.subplots_adjust(top=0.88)

    # Generate animation
    simulation = animation.FuncAnimation(fig,
                                         newFrame,
                                         fargs = (fig, supTitleText, densityPlot, pressurePlot, iePlot,
                                                  velocityXPlot, velocityYPlot, velocityZPlot,
                                                  magneticXPlot, magneticYPlot, magneticZPlot,
                                                  densityData, pressureData, ieData,
                                                  velocityXData, velocityYData, velocityZData,
                                                  magneticXData, magneticYData, magneticZData,
                                                  timeStepSamples, titleText),
                                         blit = True,
                                         frames = timeStepSamples,
                                         interval = FrameTime,
                                         repeat = False)

    FFwriter = animation.FFMpegWriter(bitrate=1000,
                                      fps=fps,
                                      codec='libx264',
                                      extra_args=['-crf','28','-preset','ultrafast','-pix_fmt','yuv420p'])
    simulation.save(filename=OutFile, writer = FFwriter)
    # simulation.save(filename=OutFile, fps=fps, dpi=dpi)
    print(f"\n\nAnimation complete. Framerate: {fps} fps, Total Number of Frames: {timeStepSamples.size}")
# ==============================================================================

# ==============================================================================
def loadData(path, yPos, zPos):

    numFiles = 870
    dims = [32, 32, 32]
    physicalSize = [1,1,1]

    np.random.random((numFiles, dims[0]))

    # Allocate Arrays
    densityData        = np.random.random((numFiles, dims[0]))
    velocityXData      = np.random.random((numFiles, dims[0]))
    velocityYData      = np.random.random((numFiles, dims[0]))
    velocityZData      = np.random.random((numFiles, dims[0]))
    pressureData       = np.random.random((numFiles, dims[0]))
    ieData             = np.random.random((numFiles, dims[0]))
    magneticXData      = np.random.random((numFiles, dims[0]))
    magneticYData      = np.random.random((numFiles, dims[0]))
    magneticZData      = np.random.random((numFiles, dims[0]))
    timeStepNum        = np.arange(0, numFiles, 1)
    positions          = np.linspace(0., 1, dims[0])

    return (densityData, velocityXData, velocityYData, velocityZData,
            pressureData, ieData, magneticXData, magneticYData, magneticZData,
            positions, timeStepNum, dims, physicalSize)
# ==============================================================================

# ==============================================================================
def setupSubPlots(fieldName, lowLim, highLim, positions, data, linestyle, linewidth, marker, markersize, color, axsArray):
    # Get the subplot coordinates to set
    if fieldName == 'Density':
        a, b = (0,0)
    elif fieldName == 'Pressure':
        a, b = (0,1)
    elif fieldName == 'Internal Energy':
        a, b = (0,2)
    elif fieldName == '$V_x
:
        a, b = (1,0)
    elif fieldName == '$V_y
:
        a, b = (1,1)
    elif fieldName == '$V_z
:
        a, b = (1,2)
    elif fieldName == '$B_x
:
        a, b = (2,0)
    elif fieldName == '$B_y
:
        a, b = (2,1)
    elif fieldName == '$B_z
:
        a, b = (2,2)
    else:
        raise ValueError('setSubPlots received invalid fieldName')

    # Set plot parameters
    axsArray[a,b].set_ylim(lowLim, highLim)
    axsArray[a,b].set_ylabel(fieldName)
    axsArray[a,b].minorticks_on()
    axsArray[a,b].grid(which = "both")

    # Set initial values
    returnPlot, = axsArray[a,b].plot(positions,
                                     data[0,:],
                                     linestyle  = linestyle,
                                     linewidth  = linewidth,
                                     marker     = marker,
                                     markersize = markersize,
                                     color      = color,
                                     label      = fieldName,
                                     animated   = True)

    return returnPlot, axsArray
# ==============================================================================

# ==============================================================================
def computeLimit(dataSet, padPercent):
    pad = np.max(np.abs([dataSet.min(), dataSet.max()])) * padPercent
    if pad == 0:
        # if the dataset doesn't exist or is zero return reasonable limits
        return -1, 1
    else:
        lowLim  = dataSet.min() - pad
        highLim = dataSet.max() + pad
        return lowLim, highLim
# ==============================================================================

# ==============================================================================
def newFrame(idx, fig, supTitleText, densityPlot, pressurePlot, iePlot,
             velocityXPlot, velocityYPlot, velocityZPlot,
             magneticXPlot, magneticYPlot, magneticZPlot,
             densityData, pressureData, ieData,
             velocityXData, velocityYData, velocityZData,
             magneticXData, magneticYData, magneticZData,
             timeStepSamples, titleText):
    titleText.set_text(f"{supTitleText} \n Time Step: {idx}")

    densityPlot  .set_ydata(densityData[idx,:])
    pressurePlot .set_ydata(pressureData[idx,:])
    iePlot       .set_ydata(ieData[idx,:])

    velocityXPlot.set_ydata(velocityXData[idx,:])
    velocityYPlot.set_ydata(velocityYData[idx,:])
    velocityZPlot.set_ydata(velocityZData[idx,:])

    magneticXPlot.set_ydata(magneticXData[idx,:])
    magneticYPlot.set_ydata(magneticYData[idx,:])
    magneticZPlot.set_ydata(magneticZData[idx,:])

    # Report progress
    if not hasattr(newFrame, "counter"):
        newFrame.counter = -1  # Accounts for first call which is performed before the animation starts
        print()

    if newFrame.counter >= 0:
        print(f'Animation is {100*(newFrame.counter/timeStepSamples.shape[0]):.1f}% complete', end='\r')

    newFrame.counter += 1

    # The return is required to make blit work
    return (titleText, densityPlot, pressurePlot, iePlot,
            velocityXPlot, velocityYPlot, velocityZPlot,
            magneticXPlot, magneticYPlot, magneticZPlot)
# ==============================================================================

main()

print(f'Time to execute: {round(default_timer()-start,2)} seconds')

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文