o
    h                    @   sN  d dl Z d dlZd dlZd dlmZmZ d dlZd dlZd dlm	Z	 d dl
Z
d dlZd dlZd dlmZ d dlZd dlZd dlZd dlmZ d dlZd dlmZmZmZmZ d dlmZmZ d dlmZ  e!e"Z#ej$dkrqej%nd Z&d	d
 Z'G dd dZ(e( Z)G dd de j*Z+G dd de+Z,G dd de,Z-e).dG dd de+Z/G dd dZ0e).dG dd de0e,Z1e).dG dd de0e-Z2G dd dZ3e).d G d!d" d"e3e,Z4e).d#G d$d% d%e3e-Z5d&d' Z6d(d) Z7e).d*G d+d, d,e-Z8G d-d. d.Z9G d/d0 d0e9Z:G d1d2 d2e:Z;G d3d4 d4e:Z<d5d6 Z=dS )7    N)BytesIOTextIOWrapper)Path)TemporaryDirectory)Image)DISPLAY_TEMPLATEINCLUDED_FRAMES
JS_INCLUDESTYLE_INCLUDE)_apicbookwin32c                 C   sP   dd }t | | | | | }t || | | | }||||||||fS )a,  
    Compute figure size so that pixels are a multiple of n.

    Parameters
    ----------
    w, h : float
        Size in inches.

    dpi : float
        The dpi.

    n : int
        The target multiple.

    Returns
    -------
    wnew, hnew : float
        The new figure size in inches.
    c                 S   sx   t | | | dkr:t t| tj| | dkr"t| tj} | S t t| tj | | dkr:t| tj } | S )Nr   )intnp	nextafterinf)xdpin r   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/matplotlib/animation.pycorrect_roundoff7   s    z*adjusted_figsize.<locals>.correct_roundoff)r   )whr   r   r   wnewhnewr   r   r   adjusted_figsize    s   r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )MovieWriterRegistryz<Registry of available writer classes by human readable name.c                 C   s   t  | _d S N)dict_registeredselfr   r   r   __init__G   s   zMovieWriterRegistry.__init__c                    s    fdd}|S )z
        Decorator for registering a class under a name.

        Example use::

            @registry.register(name)
            class Foo:
                pass
        c                    s   | j  < | S r   )r    )
writer_clsnamer"   r   r   wrapperT   s   
z-MovieWriterRegistry.register.<locals>.wrapperr   )r"   r&   r'   r   r%   r   registerJ   s   
zMovieWriterRegistry.registerc                 C   s*   z
| j | }W | S  ty   Y dS w )z
        Check if given writer is available by name.

        Parameters
        ----------
        name : str

        Returns
        -------
        bool
        F)r    KeyErrorisAvailable)r"   r&   clsr   r   r   is_availableY   s   z MovieWriterRegistry.is_availablec                 c   s"    | j D ]
}| |r|V  qdS )z-Iterate over names of available writer class.N)r    r,   r"   r&   r   r   r   __iter__k   s   

zMovieWriterRegistry.__iter__c                 C   s   g | S )z%Get a list of available MovieWriters.r   r!   r   r   r   listq      zMovieWriterRegistry.listc                 C   s$   |  |r
| j| S td| d)z,Get an available writer class from its name.zRequested MovieWriter (z) not available)r,   r    RuntimeErrorr-   r   r   r   __getitem__u   s   

zMovieWriterRegistry.__getitem__N)
__name__
__module____qualname____doc__r#   r(   r,   r.   r/   r2   r   r   r   r   r   D   s    r   c                   @   sh   e Zd ZdZdddZejdddZedd	 Z	d
d Z
ejdd Zejdd Zejdd ZdS )AbstractMovieWritera  
    Abstract base class for writing movies, providing a way to grab frames by
    calling `~AbstractMovieWriter.grab_frame`.

    `setup` is called to start the process and `finish` is called afterwards.
    `saving` is provided as a context manager to facilitate this process as ::

        with moviewriter.saving(fig, outfile='myfile.mp4', dpi=100):
            # Iterate over frames
            moviewriter.grab_frame(**savefig_kwargs)

    The use of the context manager ensures that `setup` and `finish` are
    performed as necessary.

    An instance of a concrete subclass of this class can be given as the
    ``writer`` argument of `Animation.save()`.
       Nc                 C   s8   || _ |d ur	|ni | _t|d| _t|d| _d S )Nzanimation.codecanimation.bitrate)fpsmetadatampl
_val_or_rccodecbitrate)r"   r:   r;   r>   r?   r   r   r   r#      s   zAbstractMovieWriter.__init__c                 C   s8   t |jjdd || _|| _|du r| jj}|| _dS )a  
        Setup for writing the movie file.

        Parameters
        ----------
        fig : `~matplotlib.figure.Figure`
            The figure object that contains the information for frames.
        outfile : str
            The filename of the resulting movie file.
        dpi : float, default: ``fig.dpi``
            The DPI (or resolution) for the file.  This controls the size
            in pixels of the resulting movie file.
        TstrictN)r   parentresolveoutfilefigr   r"   rE   rD   r   r   r   r   setup   s   
zAbstractMovieWriter.setupc                 C   s*   | j  \}}t|| j t|| j fS )z7A tuple ``(width, height)`` in pixels of a movie frame.)rE   get_size_inchesr   r   )r"   r   r   r   r   r   
frame_size   s   zAbstractMovieWriter.frame_sizec                 C      dS )z
        Whether this writer supports transparency.

        Writers may consult output file type and codec to determine this at runtime.
        Fr   r!   r   r   r   _supports_transparency   s   z*AbstractMovieWriter._supports_transparencyc                 K   rJ   )a=  
        Grab the image information from the figure and save as a movie frame.

        All keyword arguments in *savefig_kwargs* are passed on to the
        `~.Figure.savefig` call that saves the figure.  However, several
        keyword arguments that are supported by `~.Figure.savefig` may not be
        passed as they are controlled by the MovieWriter:

        - *dpi*, *bbox_inches*:  These may not be passed because each frame of the
           animation much be exactly the same size in pixels.
        - *format*: This is controlled by the MovieWriter.
        Nr   r"   savefig_kwargsr   r   r   
grab_frame       zAbstractMovieWriter.grab_framec                 C   rJ   ),Finish any processing for writing the movie.Nr   r!   r   r   r   finish   rO   zAbstractMovieWriter.finishc              	   o   s    t jd dkrtd | j|||g|R i | t ddi z	| V  W |   n|   w W d   dS 1 s=w   Y  dS )z
        Context manager to facilitate writing the movie file.

        ``*args, **kw`` are any parameters that should be passed to `setup`.
        savefig.bboxtightzkDisabling savefig.bbox = 'tight', as it may cause frame size to vary, which is inappropriate for animation.N)r<   rcParams_loginforG   
rc_contextrQ   )r"   rE   rD   r   argskwargsr   r   r   saving   s   
"zAbstractMovieWriter.saving)r8   NNNr   )r3   r4   r5   r6   r#   abcabstractmethodrG   propertyrI   rK   rN   rQ   
contextlibcontextmanagerrZ   r   r   r   r   r7      s    



r7   c                       sz   e Zd ZdZdgZ		d fdd	Zdd Zd fd	d
	Zdd Zdd Z	dd Z
dd Zedd Zedd Z  ZS )MovieWritera  
    Base class for writing movies.

    This is a base class for MovieWriter subclasses that write a movie frame
    data to a pipe. You cannot instantiate this class directly.
    See examples for how to use its subclasses.

    Attributes
    ----------
    frame_format : str
        The format used in writing frame data, defaults to 'rgba'.
    fig : `~matplotlib.figure.Figure`
        The figure to capture data from.
        This must be provided by the subclasses.
    rgbar8   Nc                    s>   t | tu r
tdt j||||d | jd | _|| _dS )a@  
        Parameters
        ----------
        fps : int, default: 5
            Movie frame rate (per second).
        codec : str or None, default: :rc:`animation.codec`
            The codec to use.
        bitrate : int, default: :rc:`animation.bitrate`
            The bitrate of the movie, in kilobits per second.  Higher values
            means higher quality movies, but increase the file size.  A value
            of -1 lets the underlying movie encoder select the bitrate.
        extra_args : list of str or None, optional
            Extra command-line arguments passed to the underlying movie encoder. These
            arguments are passed last to the encoder, just before the filename. The
            default, None, means to use :rc:`animation.[name-of-encoder]_args` for the
            builtin writers.
        metadata : dict[str, str], default: {}
            A dictionary of keys and values for metadata to include in the
            output file. Some keys that may be of use include:
            title, artist, genre, subject, copyright, srcform, comment.
        zNMovieWriter cannot be instantiated directly. Please use one of its subclasses.)r:   r;   r>   r?   r   N)typer`   	TypeErrorsuperr#   supported_formatsframe_format
extra_args)r"   r:   r>   r?   rg   r;   	__class__r   r   r#      s   
zMovieWriter.__init__c                 C   s   | j dkr1| j \}}t||| jd\}}||f||fkr0| jj||dd td|||| n| j \}}tjdg| j	R   ||fS )Nh264   T)forwardz?figure size in inches has been adjusted from %s x %s to %s x %szframe size in pixels is %s x %s)
r>   rE   rH   r   r   set_size_inchesrU   rV   debugrI   )r"   wohor   r   r   r   r   _adjust_frame_size%  s   
zMovieWriter._adjust_frame_sizec                    s.   t  j|||d |  \| _| _|   d S N)r   )rd   rG   rq   _w_h_runrF   rh   r   r   rG   2  s   zMovieWriter.setupc                 C   s:   |   }tdt| tj}tj||||td| _	d S )Nz%MovieWriter._run: running command: %s)stdinstdoutstderrcreationflags)
_argsrU   rV   r   _pformat_subprocess
subprocessPIPEPopensubprocess_creation_flags_proc)r"   commandr}   r   r   r   ru   :  s   zMovieWriter._runc                 C   s   | j  \}}tt| }tt| }|r(t| j jr"tj	ntj
d| |r9t| j jr3tj	ntj
d| | j jrIt| j j| j j||dS )rP   zMovieWriter stdout:
%szMovieWriter stderr:
%sN)r   communicater   r   readrU   log
returncodeloggingWARNINGDEBUGr|   CalledProcessErrorrX   )r"   outerrr   r   r   rQ   F  s$   zMovieWriter.finishc                 K   sJ   t | td | j| j| j | jj| jj	f| j
| jd| d S )Nz'MovieWriter.grab_frame: Grabbing frame.formatr   )_validate_grabframe_kwargsrU   rn   rE   rm   rs   rt   savefigr   rv   rf   r   rL   r   r   r   rN   X  s   

zMovieWriter.grab_framec                 C   s   t dS )z9Assemble list of encoder-specific command-line arguments.z)args needs to be implemented by subclass.NotImplementedErrorr!   r   r   r   rz   c  r0   zMovieWriter._argsc                 C   s   t tj| j S )z
        Return the binary path to the commandline tool used by a specific
        subclass. This is a class method so that the tool can be looked for
        before making a particular MovieWriter subclass available.
        )strr<   rT   	_exec_keyr+   r   r   r   bin_pathg  s   zMovieWriter.bin_pathc                 C   s   t |  duS )z<Return whether a MovieWriter subclass is actually available.N)shutilwhichr   r   r   r   r   r*   p     zMovieWriter.isAvailable)r8   NNNNr   )r3   r4   r5   r6   re   r#   rq   rG   ru   rQ   rN   rz   classmethodr   r*   __classcell__r   r   rh   r   r`      s     %
r`   c                       sh   e Zd ZdZ fddZdddZdd Zed	d
 Zej	dd
 Zdd Z
dd Z fddZ  ZS )FileMovieWriterz}
    `MovieWriter` for writing to individual files and stitching at the end.

    This must be sub-classed to be useful.
    c                    s"   t  j|i | tjd | _d S )Nzanimation.frame_format)rd   r#   r<   rT   rf   )r"   rX   rY   rh   r   r   r#   |  s   zFileMovieWriter.__init__Nc                 C   s   t |jjdd || _|| _|du r| jj}|| _|   |du r1t | _t	t | jj
d| _nd| _|| _d| _t | _d| _dS )a  
        Setup for writing the movie file.

        Parameters
        ----------
        fig : `~matplotlib.figure.Figure`
            The figure to grab the rendered frames from.
        outfile : str
            The filename of the resulting movie file.
        dpi : float, default: ``fig.dpi``
            The dpi of the output file. This, with the figure size,
            controls the size in pixels of the resulting movie file.
        frame_prefix : str, optional
            The filename prefix to use for temporary files.  If *None* (the
            default), files are written to a temporary directory which is
            deleted by `finish`; if not *None*, no temporary files are
            deleted.
        Tr@   Ntmpr   z
%s%%07d.%s)r   rB   rC   rE   rD   r   rq   r   _tmpdirr   r&   temp_prefix_frame_counterr/   _temp_pathsfname_format_str)r"   rE   rD   r   frame_prefixr   r   r   rG     s   
zFileMovieWriter.setupc                 C   s&   t | dr| jr| j  d S d S d S )Nr   )hasattrr   cleanupr!   r   r   r   __del__  s   zFileMovieWriter.__del__c                 C   s   | j S )z
        Format (png, jpeg, etc.) to use for saving the frames, which can be
        decided by the individual subclasses.
        )_frame_formatr!   r   r   r   rf     s   zFileMovieWriter.frame_formatc              	   C   sN   || j v r
|| _d S td|dt| j d| j d  d | j d | _d S )NzIgnoring file format z which is not supported by z; using r   z	 instead.)re   r   r   warn_externalrb   r3   )r"   rf   r   r   r   rf     s   

c                 C   s   | j | j| jf S r   )r   r   rf   r!   r   r   r   _base_temp_name  r   zFileMovieWriter._base_temp_namec                 K   s   t | t|  | j }| j| |  jd7  _td| j| t|d}| j	j
|f| j| jd| W d    d S 1 sBw   Y  d S )N   z8FileMovieWriter.grab_frame: Grabbing frame %d to path=%swbr   )r   r   r   r   r   appendrU   rn   openrE   r   rf   r   )r"   rM   pathsinkr   r   r   rN     s   "zFileMovieWriter.grab_framec              
      s^   z|    t   W | jrtd| j | j  d S d S | jr.td| j | j  w w )N'MovieWriter: clearing temporary path=%s)ru   rd   rQ   r   rU   rn   r   r!   rh   r   r   rQ     s   
zFileMovieWriter.finishNN)r3   r4   r5   r6   r#   rG   r   r]   rf   setterr   rN   rQ   r   r   r   rh   r   r   v  s    
&


r   pillowc                       sB   e Zd Zdd Zedd Zd fdd	Zdd	 Zd
d Z  Z	S )PillowWriterc                 C   rJ   NTr   r!   r   r   r   rK     s   z#PillowWriter._supports_transparencyc                 C   rJ   r   r   r   r   r   r   r*        zPillowWriter.isAvailableNc                    s   t  j|||d g | _d S rr   )rd   rG   _framesrF   rh   r   r   rG     s   
zPillowWriter.setupc              	   K   s   t | t }| jj|fi i |d| jd td| j| dddd}|	 d d dk r9| j
| d S | j
|d	 d S )
Nra   r   RGBArawr   r         RGB)r   r   rE   r   r   r   
frombufferrI   	getbuffer
getextremar   r   convert)r"   rM   bufimr   r   r   rN     s   zPillowWriter.grab_framec                 C   s4   | j d j| jd| j dd  td| j dd d S )Nr   Tr     )save_allappend_imagesdurationloop)r   saverD   r   r:   r!   r   r   r   rQ     s   

zPillowWriter.finishr   )
r3   r4   r5   rK   r   r*   rG   rN   rQ   r   r   r   rh   r   r     s    
r   c                   @   s,   e Zd ZdZdZdZdd Zedd ZdS )	
FFMpegBasez
    Mixin class for FFMpeg output.

    This is a base class for the concrete `FFMpegWriter` and `FFMpegFileWriter`
    classes.
    zanimation.ffmpeg_pathzanimation.ffmpeg_argsc                 C   s"   t | jj}|dv rdS | jdv S )N   .gif.apng.avif.webm.webpT>   bmpdpxgifpngapngavrpcfhdffv1tiffv408ljpegqtrletargaproresffvhuffhuffyuvutvideojpeg2000rawvideo	prores_aw	prores_ks)r   rD   suffixr>   r"   r   r   r   r   rK     s   
z!FFMpegBase._supports_transparencyc                 C   s  g }t | jj}|dv r|dd  | _n|d| jg | jd ur$| jntj| j }| jdkr;d|vr;|ddg n!| jdkrLd|vrL|dd	g n| jd
kr\d|vr\|g d | j	dkrk|dd| j	 g | j
 D ]\}}|d| d| g qp|| |d| jg S )Nr   r   -vcodecrj   -pix_fmtyuv420pr   -filter_complexz1split [a][b];[a] palettegen [p];[b][p] paletteuseavif)r   z.split [rgb][rgba]; [rgba] alphaextract [alpha]-mapz[rgb]r   z[alpha]r   z-bz%dkz	-metadata=z-y)r   rD   r   r>   extendrg   r<   rT   	_args_keyr?   r;   items)r"   rX   r   rg   kvr   r   r   output_args  s,   


zFFMpegBase.output_argsN)	r3   r4   r5   r6   r   r   rK   r]   r   r   r   r   r   r     s    r   ffmpegc                   @   s   e Zd ZdZdd ZdS )FFMpegWriterat  
    Pipe-based ffmpeg writer.

    Frames are streamed directly to ffmpeg via a pipe and written in a single pass.

    This effectively works as a slideshow input to ffmpeg with the fps passed as
    ``-framerate``, so see also `their notes on frame rates`_ for further details.

    .. _their notes on frame rates: https://trac.ffmpeg.org/wiki/Slideshow#Framerates
    c                 C   s\   |   dddddd| j d| jdt| jg}t tjkr#|dd	g7 }|d
dg| j	 7 }|S )N-fr   r   z-s%dx%dr   
-framerate	-loglevelerror-izpipe:)
r   rI   rf   r   r:   rU   getEffectiveLevelr   r   r   r"   rX   r   r   r   rz   K  s   
zFFMpegWriter._argsN)r3   r4   r5   r6   rz   r   r   r   r   r   ?  s    
r   ffmpeg_filec                   @   s    e Zd ZdZg dZdd ZdS )FFMpegFileWriteray  
    File-based ffmpeg writer.

    Frames are written to temporary files on disk and then stitched together at the end.

    This effectively works as a slideshow input to ffmpeg with the fps passed as
    ``-framerate``, so see also `their notes on frame rates`_ for further details.

    .. _their notes on frame rates: https://trac.ffmpeg.org/wiki/Slideshow#Framerates
    r   jpegr   r   ra   c              	   C   s   g }| j dv r|dddddd| j dd	g7 }|d
t| jd|  g7 }| js/|dt| jg7 }t t	j
kr<|ddg7 }|  g|| jS )N>   r   ra   r   image2r   r   z-video_sizer   z-pixel_formatra   r   r   z	-frames:vr   r   )rf   rI   r   r:   r   r   r   rU   r   r   r   r   r   r   r   r   r   rz   i  s   

zFFMpegFileWriter._argsN)r3   r4   r5   r6   re   rz   r   r   r   r   r   [  s    
r   c                       sL   e Zd ZdZdZdZdd Zdd Ze fdd	Z	e fd
dZ
  ZS )ImageMagickBasea  
    Mixin class for ImageMagick output.

    This is a base class for the concrete `ImageMagickWriter` and
    `ImageMagickFileWriter` classes, which define an ``input_names`` attribute
    (or property) specifying the input names passed to ImageMagick.
    zanimation.convert_pathzanimation.convert_argsc                 C   s   t | jj}|dv S )Nr   )r   rD   r   r   r   r   r   rK     s   z&ImageMagickBase._supports_transparencyc                 C   sr   | j dkrdn| j }| jd ur| jntj| j }|  dd| j dddtd| j d	d
| d| j	 g
|| j
S )Nr   ra   z-sizez%ix%iz-depth8z-delayd   z-loop0:)rf   rg   r<   rT   r   r   rI   r   r:   input_namesrD   )r"   fmtrg   r   r   r   rz     s   

zImageMagickBase._argsc                    s"   t   }|dkrtdj}|S )Nr   magick)rd   r   r<   _get_executable_info
executable)r+   binpathrh   r   r   r     s   
zImageMagickBase.bin_pathc              
      sB   zt   W S  tjy  } ztd| W Y d }~dS d }~ww )Nz"ImageMagick unavailable due to: %sF)rd   r*   r<   ExecutableNotFoundErrorrU   rn   )r+   _enfrh   r   r   r*     s   zImageMagickBase.isAvailable)r3   r4   r5   r6   r   r   rK   rz   r   r   r*   r   r   r   rh   r   r    s    r  imagemagickc                   @   s   e Zd ZdZdZdS )ImageMagickWriterz
    Pipe-based animated gif writer.

    Frames are streamed directly to ImageMagick via a pipe and written
    in a single pass.
    -N)r3   r4   r5   r6   r  r   r   r   r   r    s    r  imagemagick_filec                   @   s$   e Zd ZdZg dZedd ZdS )ImageMagickFileWriterz
    File-based animated gif writer.

    Frames are written to temporary files on disk and then stitched
    together at the end.
    r   c                 C   s   | j  d| j S )Nz*.)r   rf   r!   r   r   r   <lambda>      zImageMagickFileWriter.<lambda>N)r3   r4   r5   r6   re   r]   r  r   r   r   r   r    s    r  c                 C   s   t j| ||dS )N)Nframes	frame_dirrf   )r   r   )frame_countrf   r  r   r   r   _included_frames  s   r  c                    s2    dkrd ddd  fddt| D  S )z7frame_list should be a list of base64-encoded png filessvgzsvg+xmlz,  frames[{0}] = "data:image/{1};base64,{2}"

 c              	   3   s*    | ]\}} | |d dV  qdS )r  z\
N)r   replace).0i
frame_datarf   templater   r   	<genexpr>  s
    
z#_embedded_frames.<locals>.<genexpr>)join	enumerate)
frame_listrf   r   r!  r   _embedded_frames  s   
r'  htmlc                       s^   e Zd ZdZg dZedd Z			d fd	d
	Zd fdd	Z fddZ	dd Z
  ZS )
HTMLWriterz(Writer for JavaScript-based HTML movies.)r   r   r   r  c                 C   rJ   r   r   r   r   r   r   r*     r   zHTMLWriter.isAvailable   NFr   c	           	         sj   |rt d d}|| _| | _tjg d| jd t|d| _	|  j	d9  _	t
 ||||| d S )NzHTMLWriter ignores 'extra_args'r   )r   oncereflect)default_modeanimation.embed_limit   )rU   warningembed_frameslowerr-  r   check_in_listr<   r=   _bytes_limitrd   r#   )	r"   r:   r>   r?   rg   r;   r1  r-  embed_limitrh   r   r   r#     s   


zHTMLWriter.__init__c                    s   t |}tjddg|jd g | _d| _d| _| js2|d u r&||j	d }|j
ddd |d	 }nd }t |||| d| _d S )
Nz.htmlz.htm)outfile_extensionr   Fr   T)parentsexist_okframe)r   r   r3  r   _saved_frames_total_bytes
_hit_limitr1  	with_namestemmkdirrd   rG   _clear_temp)r"   rE   rD   r   r  r   rh   r   r   rG     s   

zHTMLWriter.setupc                    s   t | | jrM| jrd S t }| jj|f| j| jd| t	|
 d}|  jt|7  _| j| jkrEtd| j| j d| _d S | j| d S t jdi |S )Nr   asciizAnimation size has reached %s bytes, exceeding the limit of %s. If you're sure you want a larger animation embedded, set the animation.embed_limit rc parameter to a larger value (in MB). This and further frames will be dropped.Tr   )r   r1  r<  r   rE   r   rf   r   base64encodebytesgetvaluedecoder;  lenr4  rU   r0  r:  r   rd   rN   )r"   rM   f	imgdata64rh   r   r   rN     s(   
zHTMLWriter.grab_framec              
   C   s   | j rt| j| j}t| j}nt| j}t|| j| jd j| j	j}t
dddd}d|| jd < d| j }t| j	d"}|tt  |tjd
t j|||d| W d    n1 scw   Y  | jrytd	| j | j  d S d S )Nr   r  )once_checkedloop_checkedreflect_checkedchecked_checkedr   r   )idr  fill_framesintervalr   r   )r1  r'  r:  rf   rF  r   r  rB   relative_torD   r   r-  r:   r   writer	   r
   r   r   uuiduuid4hexr   rU   rn   r   )r"   rO  r  	mode_dictrP  ofr   r   r   rQ   (  s<   


zHTMLWriter.finish)r*  NNNNFr   Nr   )r3   r4   r5   r6   re   r   r*   r#   rG   rN   rQ   r   r   r   rh   r   r)    s    
r)  c                   @   s   e Zd ZdZd4ddZdd Zdd	 Zd
d Z			d5ddddZdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd6d)d*Zd7d,d-Zd.d/ Zd0d1 Zd2d3 ZdS )8	Animationa  
    A base class for Animations.

    This class is not usable as is, and should be subclassed to provide needed
    behavior.

    .. note::

        You must store the created Animation in a variable that lives as long
        as the animation should run. Otherwise, the Animation object will be
        garbage-collected and the animation stops.

    Parameters
    ----------
    fig : `~matplotlib.figure.Figure`
        The figure object used to get needed events, such as draw or resize.

    event_source : object, optional
        A class that can run a callback when desired events
        are generated, as well as be stopped and started.

        Examples include timers (see `TimedAnimation`) and file
        system notifications.

    blit : bool, default: False
        Whether blitting is used to optimize drawing.  If the backend does not
        support blitting, then this parameter has no effect.

    See Also
    --------
    FuncAnimation,  ArtistAnimation
    NFc                 C   sf   d| _ || _|o|jj| _|  | _|| _|jd| j	| _
| jjd| j| _| jr1|   d S d S )NF
draw_eventclose_event)_draw_was_started_figcanvassupports_blit_blitnew_frame_seq	frame_seqevent_sourcempl_connect_start_first_draw_id_stop	_close_id_setup_blit)r"   rE   rb  blitr   r   r   r#   o  s   

zAnimation.__init__c                 C   s   t | ddstd d S d S )Nr[  TzAnimation was deleted without rendering anything. This is most likely not intended. To prevent deletion, assign the Animation to a variable, e.g. `anim`, that exists until you output the Animation using `plt.show()` or `anim.save()`.)getattrwarningswarnr!   r   r   r   r     s
   zAnimation.__del__c                 G   sD   | j j rdS | j j| j |   | j| j | j	  dS )z
        Starts interactive animation. Adds the draw frame command to the GUI
        handler, calls show to start the event loop.
        N)
r\  r]  	is_savingmpl_disconnectre  
_init_drawrb  add_callback_stepstartr   r   r   r   rd    s   zAnimation._startc                 G   s>   | j r| jj| j | jj| j | j| j d | _d S r   )	r_  r\  r]  rn  
_resize_idrg  rb  remove_callbackrq  r   r   r   r   rf    s
   
zAnimation._stop)progress_callbackc             	      s   g}|	dur|  fdd|	D  |D ]}d|_q|du r%tjd }nt|ts<tdd |||||fD r<td|
du rCi }
nt|
}
|du rUt	 drUd	 j
 }t|d
}|dkrc jj}i }|durm||d< |duru||d< |dur}||d< |dur||d< t|trzt| }W n ty   t}td| Y nw ||fi |}tdt| d|
v rtd |
d dd }| j|| tj jjddd{ | s|
dtjd }|dkr j }|||
d< d|
d< |D ]}|  qd}dd |D }d|v rd}nt|}tdd |D  D ]+}t||D ]\}}|j|dd  |dur?||| |d!7 }q&|j d"i |
 qW d   n1 sVw   Y  W d   dS W d   dS 1 sow   Y  dS )#a  
        Save the animation as a movie file by drawing every frame.

        Parameters
        ----------
        filename : str
            The output filename, e.g., :file:`mymovie.mp4`.

        writer : `MovieWriter` or str, default: :rc:`animation.writer`
            A `MovieWriter` instance to use or a key that identifies a
            class to use, such as 'ffmpeg'.

        fps : int, optional
            Movie frame rate (per second).  If not set, the frame rate from the
            animation's frame interval.

        dpi : float, default: :rc:`savefig.dpi`
            Controls the dots per inch for the movie frames.  Together with
            the figure's size in inches, this controls the size of the movie.

        codec : str, default: :rc:`animation.codec`.
            The video codec to use.  Not all codecs are supported by a given
            `MovieWriter`.

        bitrate : int, default: :rc:`animation.bitrate`
            The bitrate of the movie, in kilobits per second.  Higher values
            means higher quality movies, but increase the file size.  A value
            of -1 lets the underlying movie encoder select the bitrate.

        extra_args : list of str or None, optional
            Extra command-line arguments passed to the underlying movie encoder. These
            arguments are passed last to the encoder, just before the output filename.
            The default, None, means to use :rc:`animation.[name-of-encoder]_args` for
            the builtin writers.

        metadata : dict[str, str], default: {}
            Dictionary of keys and values for metadata to include in
            the output file. Some keys that may be of use include:
            title, artist, genre, subject, copyright, srcform, comment.

        extra_anim : list, default: []
            Additional `Animation` objects that should be included
            in the saved movie file. These need to be from the same
            `.Figure` instance. Also, animation frames will
            just be simply combined, so there should be a 1:1 correspondence
            between the frames from the different animations.

        savefig_kwargs : dict, default: {}
            Keyword arguments passed to each `~.Figure.savefig` call used to
            save the individual frames.

        progress_callback : function, optional
            A callback function that will be called for every frame to notify
            the saving progress. It must have the signature ::

                def func(current_frame: int, total_frames: int) -> Any

            where *current_frame* is the current frame number and *total_frames* is the
            total number of frames to be saved. *total_frames* is set to None, if the
            total number of frames cannot be determined. Return values may exist but are
            ignored.

            Example code to write the progress to stdout::

                progress_callback = lambda i, n: print(f'Saving frame {i}/{n}')

        Notes
        -----
        *fps*, *codec*, *bitrate*, *extra_args* and *metadata* are used to
        construct a `.MovieWriter` instance and can only be passed if
        *writer* is a string.  If they are passed as non-*None* and *writer*
        is a `.MovieWriter`, a `RuntimeError` will be raised.
        Nc                 3   s     | ]}|j  j u r|V  qd S r   )r\  )r  animr!   r   r   r#    s    z!Animation.save.<locals>.<genexpr>Tanimation.writerc                 s   s    | ]}|d uV  qd S r   r   )r  argr   r   r   r#    s    zPassing in values for arguments fps, codec, bitrate, extra_args, or metadata is not supported when writer is an existing MovieWriter instance. These should instead be passed as arguments when creating the MovieWriter instance.	_interval     @@zsavefig.dpifigurer>   r?   rg   r;   z1MovieWriter %s unavailable; using Pillow instead.zAnimation.save using %sbbox_incheszWarning: discarding the 'bbox_inches' argument in 'savefig_kwargs' as it may cause frame size to vary, which is inappropriate for animation.c                 S   s.   t | \}}}}|t|||g d | S )Nr   )mcolorsto_rgbar   array)colorrgbar   r   r   _pre_composite_to_whiteC  s   z/Animation.save.<locals>._pre_composite_to_white)
_is_savingmanager	facecolorzsavefig.facecolorautoFtransparentr   c                 S   s   g | ]}t |d dqS )_save_countN)rj  r  r  r   r   r   
<listcomp>Y  s    z"Animation.save.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   )new_saved_frame_seqr  r   r   r   r  _  s    )ri  r   r   )!r   r[  r<   rT   
isinstancer   anyr1   r   r   ry  r=   r\  r   writersr   rU   r0  rV   rb   poprZ   r   _setattr_cmr]  rK   getget_facecolorro  sumzip_draw_next_framerN   )r"   filenamewriterr:   r   r>   r?   rg   r;   
extra_animrM   ru  all_animrv  writer_kwargsr$   r  r  frame_numbersave_count_listtotal_framesdatadr   r!   r   r     s   M




	




TzAnimation.savec                 G   s4   zt | j}| || j W dS  ty   Y dS w )z
        Handler for getting events. By default, gets the next frame in the
        sequence and hands the data off to be drawn.
        TF)nextra  r  r_  StopIteration)r"   rX   	framedatar   r   r   rq  h  s   
zAnimation._stepc                 C   s
   t | jS )z+Return a new sequence of frame information.)iter
_framedatar!   r   r   r   r`  w     
zAnimation.new_frame_seqc                 C      |   S )z8Return a new sequence of saved/cached frame information.)r`  r!   r   r   r   r  |  s   zAnimation.new_saved_frame_seqc                 C   s&   |  || | | | || d S r   )	_pre_draw_draw_frame
_post_drawr"   r  ri  r   r   r   r    s   
zAnimation._draw_next_framec                 C   s
   d| _ d S r   )r[  r!   r   r   r   ro    r  zAnimation._init_drawc                 C   s   |r
|  | j d S d S r   )_blit_clear_drawn_artistsr  r   r   r   r    s   zAnimation._pre_drawc                 C   s   t d)NzDNeeds to be implemented by subclasses to actually make an animation.r   )r"   r  r   r   r   r    r0   zAnimation._draw_framec                 C   s*   |r| j r| | j  d S | jj  d S r   )r  
_blit_drawr\  r]  	draw_idler  r   r   r   r    s   
zAnimation._post_drawc                 C   s   dd |D }|D ]#}|  }| j|t d f\}}||kr,||jj|jf| j|< q	|D ]}|j	| q/|D ]
}|jj
|j q:d S )Nc                 S      h | ]}|j qS r   axesr  r   r   r   	<setcomp>  r  z'Animation._blit_draw.<locals>.<setcomp>)	_get_view_blit_cacher  objectr{  r]  copy_from_bboxbboxr  draw_artistri  )r"   artists
updated_axaxcur_viewviewbgr  r   r   r   r    s   
zAnimation._blit_drawc              	   C   sj   dd |D }|D ])}z	| j | \}}W n	 ty   Y q	w | |kr,|jj| q	| j | q	d S )Nc                 S   r  r   r  r  r   r   r   r    r  z(Animation._blit_clear.<locals>.<setcomp>)r  r)   r  r{  r]  restore_regionr  )r"   r  r  r  r  r  r   r   r   r    s   zAnimation._blit_clearc                 C   s<   t  | _g | _| d | j |   | jjd| j	| _
d S )Nresize_event)r   r  r  r  r_  ro  r\  r]  rc  
_on_resizers  r!   r   r   r   rh    s   

zAnimation._setup_blitc                 C   sD   | j j| j | j  | j  |   | j j	d| j
| _d S )NrY  )r\  r]  rn  rs  rb  stopr  clearro  rc  _end_redrawr"   eventr   r   r   r    s   



zAnimation._on_resizec                 C   s>   |  d d | j  | jj| j | jjd| j| _d S )NFr  )	r  rb  rr  r\  r]  rn  rs  rc  r  r  r   r   r   r    s   


zAnimation._end_redrawc           
      C   s  d}t | dsjt|d}|d9 }t 1}t|d}ttjd  }|dtjd d	| j d
}| jt	||d t
| }W d   n1 sHw   Y  t|}||kr]td|| n|d| _dj|j | _t | drddg}	t| ddr~|	d |j| j| jd|	dS dS )a  
        Convert the animation to an HTML5 ``<video>`` tag.

        This saves the animation as an h264 video, encoded in base64
        directly into the HTML5 video tag. This respects :rc:`animation.writer`
        and :rc:`animation.bitrate`. This also makes use of the
        *interval* to control the speed, and uses the *repeat*
        parameter to decide whether to loop.

        Parameters
        ----------
        embed_limit : float, optional
            Limit, in MB, of the returned animation. No animation is created
            if the limit is exceeded.
            Defaults to :rc:`animation.embed_limit` = 20.0.

        Returns
        -------
        str
            An HTML5 video tag with the animation embedded as base64 encoded
            h264 video.
            If the *embed_limit* is exceeded, this returns the string
            "Video too large to embed."
        z<video {size} {options}>
  <source type="video/mp4" src="data:video/mp4;base64,{video}">
  Your browser does not support the video tag.
</video>_base64_videor.  r/  ztemp.m4vrw  rj   r9   rz  )r>   r?   r:   r  NzAnimation movie is %s bytes, exceeding the limit of %s. If you're sure you want a large animation embedded, set the animation.embed_limit rc parameter to a larger value (in MB).rA  zwidth="{}" height="{}"controlsautoplay_repeatFr    )videosizeoptionszVideo too large to embed.)r   r<   r=   r   r   r  rT   ry  r   r   rB  rC  
read_bytesrF  rU   r0  rE  r  r   rI   _video_sizerj  r   r$  )
r"   r5  	VIDEO_TAGtmpdirr   Writerr  vid64vid_lenr  r   r   r   to_html5_video  sB   



zAnimation.to_html5_videoTc                 C   s   |du rt | drd| j }|du rt| ddrdnd}t | dsPt $}t|d	}t|||d
}| jt||d | | _	W d   | j	S 1 sKw   Y  | j	S )a  
        Generate HTML representation of the animation.

        Parameters
        ----------
        fps : int, optional
            Movie frame rate (per second). If not set, the frame rate from
            the animation's frame interval.
        embed_frames : bool, optional
        default_mode : str, optional
            What to do when the animation ends. Must be one of ``{'loop',
            'once', 'reflect'}``. Defaults to ``'loop'`` if the *repeat*
            parameter is True, otherwise ``'once'``.

        Returns
        -------
        str
            An HTML representation of the animation embedded as a js object as
            produced with the `.HTMLWriter`.
        Nry  r   r  Fr   r+  _html_representationz	temp.html)r:   r1  r-  r  )
r   ry  rj  r   r   r)  r   r   	read_textr  )r"   r:   r1  r-  r  r   r  r   r   r   	to_jshtml9  s*   



zAnimation.to_jshtmlc                 C   s.   t jd }|dkr|  S |dkr|  S dS )z#IPython display hook for rendering.zanimation.htmlhtml5jshtmlN)r<   rT   r  r  )r"   r  r   r   r   _repr_html_e  s   
zAnimation._repr_html_c                 C   .   | j   | jr| jD ]	}|d qdS dS )zPause the animation.FN)rb  r  r_  r  set_animatedr"   artistr   r   r   pausem     

zAnimation.pausec                 C   r  )zResume the animation.TN)rb  rr  r_  r  r  r  r   r   r   resumet  r  zAnimation.resumeNF)	NNNNNNNNNr   )NTN)r3   r4   r5   r6   r#   r   rd  rf  r   rq  r`  r  r  ro  r  r  r  r  r  rh  r  r  r  r  r  r  r  r   r   r   r   rX  M  s>    
!
 :

	
N,rX  c                       s2   e Zd ZdZ		d
 fdd	Z fdd	Z  ZS )TimedAnimationa}  
    `Animation` subclass for time-based animation.

    A new frame is drawn every *interval* milliseconds.

    .. note::

        You must store the created Animation in a variable that lives as long
        as the animation should run. Otherwise, the Animation object will be
        garbage-collected and the animation stops.

    Parameters
    ----------
    fig : `~matplotlib.figure.Figure`
        The figure object used to get needed events, such as draw or resize.
    interval : int, default: 200
        Delay between frames in milliseconds.
    repeat_delay : int, default: 0
        The delay in milliseconds between consecutive animation runs, if
        *repeat* is True.
    repeat : bool, default: True
        Whether the animation repeats when the sequence of frames is completed.
    blit : bool, default: False
        Whether blitting is used to optimize drawing.
       r   TNc                    sX   || _ |d ur	|nd| _|| _|d u r|jj| j d}t j|g|R d|i| d S )Nr   )rP  rb  )ry  _repeat_delayr  r]  	new_timerrd   r#   )r"   rE   rP  repeat_delayrepeatrb  rX   rY   rh   r   r   r#     s   "zTimedAnimation.__init__c                    s|   t  j| }|s7| jr|   |  | _| j| j_dS | 	  | j
r*| jj| j | jj| j d| _dS | j| j_dS )zHandler for getting events.TNF)rd   rq  r  ro  r`  ra  r  rb  rP  r  r_  r\  r]  rn  rs  rg  ry  )r"   rX   still_goingrh   r   r   rq    s   


zTimedAnimation._step)r  r   TN)r3   r4   r5   r6   r#   rq  r   r   r   rh   r   r  |  s    r  c                       s<   e Zd ZdZ fddZ fddZdd Zdd	 Z  ZS )
ArtistAnimationa  
    `TimedAnimation` subclass that creates an animation by using a fixed
    set of `.Artist` objects.

    Before creating an instance, all plotting should have taken place
    and the relevant artists saved.

    .. note::

        You must store the created Animation in a variable that lives as long
        as the animation should run. Otherwise, the Animation object will be
        garbage-collected and the animation stops.

    Parameters
    ----------
    fig : `~matplotlib.figure.Figure`
        The figure object used to get needed events, such as draw or resize.
    artists : list
        Each list entry is a collection of `.Artist` objects that are made
        visible on the corresponding frame.  Other artists are made invisible.
    interval : int, default: 200
        Delay between frames in milliseconds.
    repeat_delay : int, default: 0
        The delay in milliseconds between consecutive animation runs, if
        *repeat* is True.
    repeat : bool, default: True
        Whether the animation repeats when the sequence of frames is completed.
    blit : bool, default: False
        Whether blitting is used to optimize drawing.
    c                    s*   g | _ || _t j|g|R i | d S r   )r  r  rd   r#   )r"   rE   r  rX   rY   rh   r   r   r#     s   zArtistAnimation.__init__c                    sp   t    t }|  D ]}|D ]}|d || j | |vr*||  qq|D ]}|j	
  q.d S r  )rd   ro  setr`  set_visibler  r_  
get_figureaddr]  r  )r"   figsrG  r  rE   rh   r   r   ro    s   

zArtistAnimation._init_drawc                 C   s.   |r
|  | j dS | jD ]}|d qdS )z#Clears artists from the last frame.FN)r  r  r  )r"   r  ri  r  r   r   r   r    s
   
zArtistAnimation._pre_drawc                 C   s   || _ |D ]}|d qd S r   )r  r  )r"   r  r  r   r   r   r    s   zArtistAnimation._draw_frame)	r3   r4   r5   r6   r#   ro  r  r  r   r   r   rh   r   r    s    	
r  c                       sP   e Zd ZdZ		ddd fddZdd Zd	d
 Z fddZdd Z  Z	S )FuncAnimationa?  
    `TimedAnimation` subclass that makes an animation by repeatedly calling
    a function *func*.

    .. note::

        You must store the created Animation in a variable that lives as long
        as the animation should run. Otherwise, the Animation object will be
        garbage-collected and the animation stops.

    Parameters
    ----------
    fig : `~matplotlib.figure.Figure`
        The figure object used to get needed events, such as draw or resize.

    func : callable
        The function to call at each frame.  The first argument will
        be the next value in *frames*.   Any additional positional
        arguments can be supplied using `functools.partial` or via the *fargs*
        parameter.

        The required signature is::

            def func(frame, *fargs) -> iterable_of_artists

        It is often more convenient to provide the arguments using
        `functools.partial`. In this way it is also possible to pass keyword
        arguments. To pass a function with both positional and keyword
        arguments, set all arguments as keyword arguments, just leaving the
        *frame* argument unset::

            def func(frame, art, *, y=None):
                ...

            ani = FuncAnimation(fig, partial(func, art=ln, y='foo'))

        If ``blit == True``, *func* must return an iterable of all artists
        that were modified or created. This information is used by the blitting
        algorithm to determine which parts of the figure have to be updated.
        The return value is unused if ``blit == False`` and may be omitted in
        that case.

    frames : iterable, int, generator function, or None, optional
        Source of data to pass *func* and each frame of the animation

        - If an iterable, then simply use the values provided.  If the
          iterable has a length, it will override the *save_count* kwarg.

        - If an integer, then equivalent to passing ``range(frames)``

        - If a generator function, then must have the signature::

             def gen_function() -> obj

        - If *None*, then equivalent to passing ``itertools.count``.

        In all of these cases, the values in *frames* is simply passed through
        to the user-supplied *func* and thus can be of any type.

    init_func : callable, optional
        A function used to draw a clear frame. If not given, the results of
        drawing from the first item in the frames sequence will be used. This
        function will be called once before the first frame.

        The required signature is::

            def init_func() -> iterable_of_artists

        If ``blit == True``, *init_func* must return an iterable of artists
        to be re-drawn. This information is used by the blitting algorithm to
        determine which parts of the figure have to be updated.  The return
        value is unused if ``blit == False`` and may be omitted in that case.

    fargs : tuple or None, optional
        Additional arguments to pass to each call to *func*. Note: the use of
        `functools.partial` is preferred over *fargs*. See *func* for details.

    save_count : int, optional
        Fallback for the number of values from *frames* to cache. This is
        only used if the number of frames cannot be inferred from *frames*,
        i.e. when it's an iterator without length or a generator.

    interval : int, default: 200
        Delay between frames in milliseconds.

    repeat_delay : int, default: 0
        The delay in milliseconds between consecutive animation runs, if
        *repeat* is True.

    repeat : bool, default: True
        Whether the animation repeats when the sequence of frames is completed.

    blit : bool, default: False
        Whether blitting is used to optimize drawing.  Note: when using
        blitting, any animated artists will be drawn according to their zorder;
        however, they will be drawn on top of any previous artists, regardless
        of their zorder.

    cache_frame_data : bool, default: True
        Whether frame data is cached.  Disabling cache might be helpful when
        frames contain large objects.
    NT)cache_frame_datac          
         sJ  |r|_ nd_ |_|_|_ d u rtj_n`t r# _nXt	 ra|
ddr= _ ffdd	}	|	_n fdd_t dr`t _|d ur`td	|d
t d n fdd_ _|d ur{td	|d d jd u r|rtd d|d d}|_g _t j|fi | g _d S )Nr   r  Tc                 3   s$    t  jd\} _|E d H  d S )Nrk   )	itertoolstee	_tee_from)framesthisr!   r   r   iter_frames  s   z+FuncAnimation.__init__.<locals>.iter_framesc                      s   t  S r   )r  r   r  r   r   r        z(FuncAnimation.__init__.<locals>.<lambda>__len__z%You passed in an explicit save_count=z0 which is being ignored in favor of len(frames)=.c                      s   t t S r   )r  ranger   r  r   r   r    s    z+ which is being ignored in favor of frames=zframes=ze which we can infer the length of, did not pass an explicit *save_count* and passed cache_frame_data=z.  To avoid a possibly unbounded cache, frame data caching has been disabled. To suppress this warning either pass `cache_frame_data=False` or `save_count=MAX_FRAMES`.F)rz   _func
_init_funcr  r  count	_iter_gencallabler   iterabler  r  r   rF  r   r   _cache_frame_data	_save_seqrd   r#   )
r"   rE   funcr  	init_funcfargs
save_countr  rY   r  rh   )r  r"   r   r#   u  sX   




zFuncAnimation.__init__c                 C   r  r   )r  r!   r   r   r   r`    r0   zFuncAnimation.new_frame_seqc                    sR   | j rt| j | _t| jS | jd u r |    fdd}| S t|  | jS )Nc                   3   s&    z	 t  V  q ty   Y d S w r   )r  r  r   ra  r   r   gen  s   
z.FuncAnimation.new_saved_frame_seq.<locals>.gen)r
  r/   _old_saved_seqr  r  r`  r  islice)r"   r  r   r  r   r    s   

z!FuncAnimation.new_saved_frame_seqc                    s   t    | jd u r(zt|  }W n ty!   td Y d S w | | n|  | _	| j
rE| j	d u r9td| j	D ]}|| j
 q<g | _d S )NzCan not start iterating the frames for the initial draw. This can be caused by passing in a 0 length sequence for *frames*.

If you passed *frames* as a generator it may be exhausted due to a previous display or save.z7The init_func must return a sequence of Artist objects.)rd   ro  r  r  r`  r  rk  rl  r  r  r_  r1   r  r
  )r"   r   r  rh   r   r   ro    s$   





zFuncAnimation._init_drawc                 C   s   | j r| j| | j| j d  | _| j|g| jR  | _| jr\td}zt	| j W n
 t
y6   |d w | jD ]}t|tjjsE|q:t| jdd d| _| jD ]
}|| j qSd S d S )Nz@The animation function must return a sequence of Artist objects.c                 S   r  r   )
get_zorder)r   r   r   r   r    r  z+FuncAnimation._draw_frame.<locals>.<lambda>)key)r	  r
  r   r  r  rz   r  r_  r1   r  rc   r  r<   r  Artistsortedr  )r"   r  r   r  r  r   r   r   r    s,   

zFuncAnimation._draw_frame)NNNN)
r3   r4   r5   r6   r#   r`  r  ro  r  r   r   r   rh   r   r    s    fE r  c                 C   sH   t jd dkrtdt jd ddD ]}|| v r!td|qd S )NrR   rS   zmpl.rcParams['savefig.bbox']=z^ must not be 'tight' as it may cause frame size to vary, which is inappropriate for animation.)r   r|  r   z.grab_frame got an unexpected keyword argument )r<   rT   
ValueErrorrc   )rM   r   r   r   r   r     s   r   )>r[   rB  r^   ior   r   r  r   pathlibr   r   r|   systempfiler   rS  rk  numpyr   PILr   
matplotlibr<   matplotlib._animation_datar   r   r	   r
   r   r   matplotlib.colorscolorsr}  	getLoggerr3   rU   platformCREATE_NO_WINDOWr   r   r   r  ABCr7   r`   r   r(   r   r   r   r   r  r  r  r  r'  r)  rX  r  r  r  r   r   r   r   r   <module>   sp    
$8f g#>$2l    3EM  	