B
    &[¨_*1  ã               @   sX   d 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 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Úcollections)Ú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-install-l29rncou/plotly/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	r”xNd|jfd|jfd|jj	fdt 
¡ fgD ]"\}}|  |¡rn|| |  }} P qnW |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.NÚ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_transform5   s,    



zExporter.process_transformc          	   C   s@   | j j|t |¡d  x|jD ]}|  |¡ q W W d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   q   s    zExporter.crawl_figc          
   C   s„  | j j|t |¡db x|jD ]}|  ||¡ q"W x|jD ]}|  ||¡ q>W xRt|j	j
|jj
|jgdddgƒD ].\}}t|dƒrt| ¡ rt| j|||j|d qtW x(|jD ]}t|tjjƒr®|  ||¡ q®W x|jD ]}|  ||¡ qØW x|jD ]}|  ||¡ qôW x|jD ]}|  ||¡ qW | ¡ }	|	dk	rvt ||	¡}
| j j|	|
d |
d	 rl|  ||	¡ W dQ R X W d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_patchr   Údraw_collectionZimagesÚ
draw_imageZ
get_legendZget_legend_propertiesZdraw_legendÚcrawl_legend)r
   r    Úliner2   ZttpZartistÚpatchÚ
collectionÚimager*   r%   r   r   r   r&   x   s4    

zExporter.crawl_axc          	   C   s4  t tj|jddƒ}| |j¡ x|D ]}| d| ¡  ¡ t|t	j
jƒr`| | ¡ d ¡ y¦t|t	j
jƒr„| j|||jd n€t|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(W 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   r1   r4   ZFancyBboxPatchZPatchr5   r   r2   r3   r(   r-   r+   ZLine2Dr,   r   Ú
Collectionr6   r   r   ÚNotImplementedError)r
   r    r*   ZlegendElementsÚchildr   r   r   r8   —   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_line)r!   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    r9   r!   rH   r   rI   rJ   r/   r   r   r   r,   ·   s$    



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_text)r!   )r2   ÚpositionrH   r)   ÚstylerK   N)r(   rL   Úget_positionr$   r   Zget_text_styler	   r-   )
r
   r    r2   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_path)r!   )Úfill)r   rH   Ú	pathcodesrO   rK   N)	r   ÚSVG_pathÚget_pathrL   r$   Zget_path_styleZget_fillr	   Z	draw_path)	r
   r    r:   r!   ZverticesrS   r   rH   rI   r   r   r   r5   Û   s    zExporter.draw_patchc          
      sä   |  ¡ \‰}}}ˆj|ˆ ||d\}}ˆjˆˆ ˆd}	dd„ |D ƒ}
‡ ‡‡‡fdd„|
D ƒ}
| ¡ }ydd„ |D ƒ}W n tk
rŠ   Y nX | ¡ | ¡ | ¡ |j| ¡ dœ}ddd	œ}|| 	¡  }ˆj
j|
|	||||||d
 dS )zAProcess a matplotlib collection and call renderer.draw_collection)r!   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   rW   )r    r>   r
   r   r   r   rX   ö   s   c             S   s   g | ]}|  ¡ ‘qS r   )Z
get_matrix)rV   Útr   r   r   rX   þ   s    )Z	linewidthZ	facecolorZ	edgecolorÚalphaÚzorderÚbeforeÚafter)r   Zscreen)Ú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   Zget_offset_positionr	   Zdraw_path_collection)r
   r    r;   r>   Zforce_offsettransZtransOffsetr`   r^   Zoffset_coordsZpath_coordsZprocessed_pathsr_   rb   Zoffset_dictra   r   )r    r>   r
   r   r   r6   é   s:    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   )rZ   r[   )ZimdataZextentrH   rO   rK   N)r	   r7   r   Zimage_to_base64Z
get_extentZ	get_alpharA   )r
   r    r<   r   r   r   r7     s    
zExporter.draw_image)T)NNFN)N)NN)N)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ústaticmethodr$   r   r&   r8   r,   r-   r5   r6   r7   r   r   r   r   r      s   
 : 


 
+r   )rg   r   r   Ú r   r1   r   r   Zmatplotlib.backends.backend_aggr   Úobjectr   r   r   r   r   Ú<module>   s   