U
    TZf.                     @   sT   d Z ddlZddlZddlmZ ddlZddlmZ ddlmZ G dd de	Z
dS )	z
Matplotlib Exporter
===================
This submodule contains tools for crawling a matplotlib figure and exporting
relevant pieces to a renderer.
    N   )utils)
transforms)FigureCanvasAggc                   @   sx   e Zd ZdZdddZdd Zedd	d
Zdd Zdd Z	dd Z
dddZdddZdddZd ddZdd ZdS )!Exportera  Matplotlib Exporter

    Parameters
    ----------
    renderer : Renderer object
        The renderer object called by the exporter to create a figure
        visualization.  See mplexporter.Renderer for information on the
        methods which should be defined within the renderer.
    close_mpl : bool
        If True (default), close the matplotlib figure as it is rendered. This
        is useful for when the exporter is used within the notebook, or with
        an interactive matplotlib backend.
    Tc                 C   s   || _ || _d S )N)	close_mplrenderer)selfr   r    r
   L/tmp/pip-unpacked-wheel-5ksk5baj/plotly/matplotlylib/mplexporter/exporter.py__init__   s    zExporter.__init__c                 C   sR   |j dkrt|}|jt d|jd | jrDddlm} |	| | 
| dS )z
        Run the exporter on the given figure

        Parmeters
        ---------
        fig : matplotlib.Figure instance
            The figure to export
        NZpng)formatdpir   )canvasr   ZsavefigioBytesIOr   r   Zmatplotlib.pyplotZpyplotclose	crawl_fig)r	   figr   Zpltr
   r
   r   run#   s    

zExporter.runNFc                 C   s   t | tjrtd |dk	r8|dk	r4| | |}|} d}|dk	rd|jfd|jfd|jj	fdt
 ffD ]$\}}| |rl|| |  }}  qql|dk	r|r|| || fS || |fS n|r|| fS |S dS )a?  Process the transform and convert data to figure or data coordinates

        Parameters
        ----------
        transform : matplotlib Transform object
            The transform applied to the data
        ax : matplotlib Axes object (optional)
            The axes the data is associated with
        data : ndarray (optional)
            The array of data to be transformed.
        return_trans : bool (optional)
            If true, return the final transform of the data
        force_trans : matplotlib.transform instance (optional)
            If supplied, first force the data to this transform

        Returns
        -------
        code : string
            Code is either "data", "axes", "figure", or "display", indicating
            the type of coordinates output.
        transform : matplotlib transform
            the transform used to map input data to output data.
            Returned only if return_trans is True
        new_data : ndarray
            Data transformed to match the given coordinate code.
            Returned only if data is specified
        zMBlended transforms not yet supported. Zoom behavior may not work as expected.NZdisplaydataaxesfigure)
isinstancer   ZBlendedGenericTransformwarningswarn	transformZ	transData	transAxesr   ZtransFigureZIdentityTransformZcontains_branch)r   axr   Zreturn_transforce_transcodecZtransr
   r
   r   process_transform7   s2    


zExporter.process_transformc              	   C   s<   | j j|t|d |jD ]}| | qW 5 Q R X dS )z%Crawl the figure and process all axes)r   propsN)r   Zdraw_figurer   Zget_figure_propertiesr   crawl_ax)r	   r   r   r
   r
   r   r   x   s    
zExporter.crawl_figc              
   C   sf  | j j|t|dD |jD ]}| || q |jD ]}| || q8t|j	j
|jj
|jgdddgD ].\}}t|drj| rj| j|||j|d qj|jD ]}t|tjjr| || q|jD ]}| || q|jD ]}| || q|jD ]}| || q| }	|	dk	rXt||	}
| j j|	|
d |
d	 rN| ||	 W 5 Q R X W 5 Q R X dS )
z.Crawl the axes and process all elements within)r   r#   ZxlabelZylabeltitleget_text)r   	text_typeN)legendr#   Zvisible)r   Z	draw_axesr   Zget_axes_propertieslines	draw_lineZtexts	draw_textzipZxaxislabelZyaxisr%   hasattrr&   r   Zartistsr   
matplotlibtextTextpatches
draw_patchcollectionsdraw_collectionZimages
draw_imageZ
get_legendZget_legend_propertiesZdraw_legendcrawl_legend)r	   r   liner0   ZttpZartistpatch
collectionimager(   r#   r
   r
   r   r$   ~   s4    







zExporter.crawl_axc              	   C   s.  t tj|jdd}||j |D ]}|d|   t|t	j
jr\|| d  zt|t	j
jr| j|||jd nt|t	jjr| dkr| j|||jd nRt|t	jjr| j|||jd n0t|t	jjr| j|||jd ntd|  W q$ tk
r&   td|  Y q$X q$d	S )
zE
        Recursively look through objects in legend children
        T)ZskipContainersg    .Ar   r   None)force_pathtransz Legend element %s not impementedN)listr   Ziter_all_childrenZ_legend_boxappendZlegendPatchZ
set_zorder
get_zorderr   r/   r2   ZFancyBboxPatchZPatchr3   r   r0   r1   r&   r+   r)   ZLine2Dr*   r4   
Collectionr5   r   r   NotImplementedError)r	   r   r(   ZlegendElementschildr
   r
   r   r7      s*    
zExporter.crawl_legendc           	      C   s   | j | || |d\}}t|}|d dkrD|d dkrDd}t|}|d dksl|d d	 jd	krpd}| }|s|r| jj	||||||d
 dS )z5Process a matplotlib line and call renderer.draw_liner<   Z	dasharrayNZ	drawstyledefaultmarker)r=   noneNZ
markerpathr   )r   coordinates	linestylemarkerstyler-   mplobj)
r"   get_transformZ
get_xydatar   Zget_line_styleZget_marker_stylesizeZ	get_labelr   Zdraw_marked_line)	r	   r   r8   r   rH   r   rI   rJ   r-   r
   r
   r   r*      s2       



zExporter.draw_linec           
      C   sX   |  }|rT| }| }| j||||d\}}t|}	| jj|||||	|d dS )z<Process a matplotlib text object and call renderer.draw_textr<   )r0   positionrH   r'   stylerK   N)r&   rL   get_positionr"   r   Zget_text_styler   r+   )
r	   r   r0   r   r'   contentr   rN   ZcoordsrO   r
   r
   r   r+      s&       

zExporter.draw_textc           	      C   s\   t | \}}| }| j||||d\}}t j|| d}| jj|||||d dS )z=Process a matplotlib patch object and call renderer.draw_pathr<   )fill)r   rH   	pathcodesrO   rK   N)	r   SVG_pathget_pathrL   r"   Zget_path_styleZget_fillr   Z	draw_path)	r	   r   r9   r   ZverticesrS   r   rH   rI   r
   r
   r   r3      s        
zExporter.draw_patchc              
      s   |  \}}}j| ||d\}}j d}	dd |D }
 fdd|
D }
| }zdd |D }W n tk
r   Y nX | | | |j| d}ddd	}t	|d
r||
  nd}jj|
|	||||||d dS )zAProcess a matplotlib collection and call renderer.draw_collectionr<   c                 S   s   g | ]}t |qS r
   )r   rT   .0pathr
   r
   r   
<listcomp>  s     z,Exporter.draw_collection.<locals>.<listcomp>c                    s.   g | ]&}j  |d  dd |d fqS )r   r<   r   )r"   rV   r   r>   r	   r   r
   r   rY     s      c                 S   s   g | ]}|  qS r
   )Z
get_matrix)rW   tr
   r
   r   rY     s     )Z	linewidthZ	facecolorZ	edgecoloralphazorderbeforeafter)r   Zscreenget_offset_position)pathsZpath_coordinatespath_transformsoffsetsZoffset_coordinatesoffset_orderstylesrK   N)Z_prepare_pointsr"   Zget_transformsAttributeErrorZget_linewidthsZget_facecolorsZget_edgecolorsZ_alpharA   r.   r`   r   Zdraw_path_collection)r	   r   r:   r>   Zforce_offsettransZtransOffsetrc   ra   Zoffset_coordsZpath_coordsZprocessed_pathsrb   re   Zoffset_dictrd   r
   rZ   r   r5      sL       



zExporter.draw_collectionc                 C   s2   | j jt|| d| | d|d dS )z>Process a matplotlib image object and call renderer.draw_imager   )r\   r]   )ZimdataZextentrH   rO   rK   N)r   r6   r   Zimage_to_base64Z
get_extentZ	get_alpharA   )r	   r   r;   r
   r
   r   r6   4  s    zExporter.draw_image)T)NNFN)N)NN)N)NN)__name__
__module____qualname____doc__r   r   staticmethodr"   r   r$   r7   r*   r+   r3   r5   r6   r
   r
   r
   r   r      s&   
       @ 


   
;r   )rj   r   r    r   r/   r   Zmatplotlib.backends.backend_aggr   objectr   r
   r
   r
   r   <module>   s   