3
ƽh 5                 @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ	 G dd dZ
G dd	 d	eZG d
d de
Zdd ZG dd de
ZeedZG dd de
ZeedZG dd de
ZG dd de
ZdS )z
Defines classes for path effects. The path effects are supported in `~.Text`,
`~.Line2D` and `~.Patch`.

.. seealso::
   :doc:`/tutorials/advanced/patheffects_guide`
    )RendererBase)colors)patches)
transformsc               @   s4   e Zd ZdZdddZdd Zdd Zdd
dZd	S )AbstractPathEffectz
    A base class for path effects.

    Subclasses should override the ``draw_path`` method to add effect
    functionality.
            c             C   s
   || _ dS )z
        Parameters
        ----------
        offset : pair of floats
            The offset to apply to the path, measured in points.
        N)_offset)selfoffset r   </tmp/pip-build-7iwl8md4/matplotlib/matplotlib/patheffects.py__init__   s    zAbstractPathEffect.__init__c             C   s   t j jt|j| j S )z(Apply the offset to the given transform.)mtransformsZAffine2D	translatemappoints_to_pixelsr   )r	   rendererr   r   r   _offset_transform    s    z$AbstractPathEffect._offset_transformc             C   sl   |j  }|jdd}|r$|jf | xB|j D ]6\}}t|d| d}t|s\tdj||| q.W |S )z
        Update the given GraphicsCollection with the given
        dictionary of properties. The keys in the dictionary are used to
        identify the appropriate set_ method on the gc.

        dashesNset_zUnknown property {0})copypopZ
set_dashesitemsgetattrcallableAttributeErrorformat)r	   gcZnew_gc_dictr   kvZ
set_methodr   r   r   
_update_gc%   s    zAbstractPathEffect._update_gcNc             C   s    t |tr|j}|j||||S )z
        Derived should override this method. The arguments are the same
        as :meth:`matplotlib.backend_bases.RendererBase.draw_path`
        except the first argument is a renderer.

        )
isinstancePathEffectRenderer	_renderer	draw_path)r	   r   r   tpathaffinergbFacer   r   r   r$   9   s    
zAbstractPathEffect.draw_pathr   r   )r(   )N)__name__
__module____qualname____doc__r   r   r    r$   r   r   r   r   r      s
   
	r   c               @   sJ   e Zd ZdZdd Zdd ZdddZd	d
 Zdd Zdd Z	dd Z
dS )r"   aw  
    Implements a Renderer which contains another renderer.

    This proxy then intercepts draw calls, calling the appropriate
    :class:`AbstractPathEffect` draw method.

    .. note::
        Not all methods have been overridden on this RendererBase subclass.
        It may be necessary to add further methods to extend the PathEffects
        capabilities further.
    c             C   s   || _ || _dS )z
        Parameters
        ----------
        path_effects : iterable of :class:`AbstractPathEffect`
            The path effects which this renderer represents.
        renderer : `matplotlib.backend_bases.RendererBase` subclass

        N)_path_effectsr#   )r	   path_effectsr   r   r   r   r   S   s    	zPathEffectRenderer.__init__c             C   s   | j || jS )N)	__class__r#   )r	   r.   r   r   r   copy_with_path_effect_   s    z(PathEffectRenderer.copy_with_path_effectNc             C   s(   x"| j D ]}|j| j|||| qW d S )N)r-   r$   r#   )r	   r   r%   r&   r'   path_effectr   r   r   r$   b   s    zPathEffectRenderer.draw_pathc       	      O   s`   t | jdkr(tj| ||||f||S x2| jD ](}| j|g}|j||||f|| q0W d S )N   )lenr-   r   draw_markersr0   )	r	   r   Zmarker_pathZmarker_transpathargskwargsr1   r   r   r   r   r4   g   s    

zPathEffectRenderer.draw_markersc             O   s\   t | jdkr&tj| |||f||S x0| jD ]&}| j|g}|j|||f|| q.W d S )Nr2   )r3   r-   r   draw_path_collectionr0   )r	   r   Zmaster_transformpathsr6   r7   r1   r   r   r   r   r8   z   s    
z'PathEffectRenderer.draw_path_collectionc             C   s@   | j ||||||\}}	|j }
|jd | j|||	|
d d S )Ng        )r'   )Z_get_text_path_transformZget_rgbset_linewidthr$   )r	   r   xyspropZangleZismathr5   Z	transformcolorr   r   r   _draw_text_as_path   s
    
z%PathEffectRenderer._draw_text_as_pathc             C   s$   |dkrt | j|S tj| |S d S )	Nflipyget_canvas_width_heightnew_gcr   
_text2pathheightwidth)rA   rB   rC   r   rD   rE   rF   )r   r#   object__getattribute__)r	   namer   r   r   rH      s    z#PathEffectRenderer.__getattribute__)N)r)   r*   r+   r,   r   r0   r$   r4   r8   r@   rH   r   r   r   r   r"   F   s   
r"   c               @   s   e Zd ZdZdS )Normalz
    The "identity" PathEffect.

    The Normal PathEffect's sole purpose is to draw the original artist with
    no special path effect.
    N)r)   r*   r+   r,   r   r   r   r   rJ      s   rJ   c             C   s\   G dd d| }d| j  |_ d| j  |_d| j  d| j  d| j  d|_| jj|j_|S )zO
    Create a PathEffect class combining *effect_class* and a normal draw.
    c                   s   e Zd Z fddZ  ZS )z)_subclass_with_normal.<locals>.withEffectc                s(   t  j||||| |j|||| d S )N)superr$   )r	   r   r   r%   r&   r'   )r/   r   r   r$      s    z3_subclass_with_normal.<locals>.withEffect.draw_path)r)   r*   r+   r$   __classcell__r   r   )r/   r   
withEffect   s   rM   withz*
    A shortcut PathEffect for applying `.z` and then
    drawing the original Artist.

    With this class you can use ::

        artist.set_path_effects([path_effects.withzN()])

    as a shortcut for ::

        artist.set_path_effects([path_effects.zA(),
                                 path_effects.Normal()])
    )r)   r+   r,   r$   )effect_classrM   r   r   r   _subclass_with_normal   s     rP   c                   s*   e Zd ZdZd fdd	Zdd Z  ZS )	Strokez0A line based PathEffect which re-draws a stroke.r   c                s   t  j| || _dS )z
        The path will be stroked with its gc updated with the given
        keyword arguments, i.e., the keyword arguments should be valid
        gc parameter values.
        N)rK   r   _gc)r	   r
   r7   )r/   r   r   r      s    zStroke.__init__c             C   sF   |j  }|j| | j|| j}|j|||| j| | |j  dS )zDraw the path with updated gc.N)rC   copy_propertiesr    rR   r$   r   restore)r	   r   r   r%   r&   r'   gc0r   r   r   r$      s    
zStroke.draw_pathr   r   )rV   )r)   r*   r+   r,   r   r$   rL   r   r   )r/   r   rQ      s   	rQ   )rO   c                   s*   e Zd ZdZd fdd	Zdd Z  ZS )SimplePatchShadowz#A simple shadow via a filled patch.   N333333?c                sJ   t  j| |dkr|| _ntj|| _|dkr4d}|| _|| _|| _dS )a  
        Parameters
        ----------
        offset : pair of floats
            The offset of the shadow in points.
        shadow_rgbFace : color
            The shadow color.
        alpha : float, default: 0.3
            The alpha transparency of the created shadow patch.
            http://matplotlib.1069221.n5.nabble.com/path-effects-question-td27630.html
        rho : float, default: 0.3
            A scale factor to apply to the rgbFace color if `shadow_rgbFace`
            is not specified.
        **kwargs
            Extra keywords are stored and passed through to
            :meth:`AbstractPathEffect._update_gc`.

        Ng333333?)rK   r   _shadow_rgbFacemcolorsto_rgba_alpha_rhorR   )r	   r
   shadow_rgbFacealpharhor7   )r/   r   r   r      s    zSimplePatchShadow.__init__c             C   s   |j  }|j| | jdkrP|p"ddd \}}}	|| j || j |	| j f}
n| j}
|jd |j| j |jd | j|| j	}|j
|||| j| |
 |j  dS )z
        Overrides the standard draw_path to add the shadow offset and
        necessary color changes for the shadow.
        N      ?   noner   )rb   rb   rb   )rC   rS   rZ   r^   set_foreground	set_alphar]   r:   r    rR   r$   r   rT   )r	   r   r   r%   r&   r'   rU   rgbr_   r   r   r   r$     s    



zSimplePatchShadow.draw_pathrX   rj   )rk   NNrY   )r)   r*   r+   r,   r   r$   rL   r   r   )r/   r   rW      s
     #rW   c                   s*   e Zd ZdZd fdd	Zdd Z  ZS )SimpleLineShadowzA simple shadow via a line.rX   r   333333?c                s>   t  j| |dkr|| _ntj|| _|| _|| _|| _dS )a  
        Parameters
        ----------
        offset : pair of floats
            The offset to apply to the path, in points.
        shadow_color : color, default: 'black'
            The shadow color.
            A value of ``None`` takes the original artist's color
            with a scale factor of *rho*.
        alpha : float, default: 0.3
            The alpha transparency of the created shadow patch.
        rho : float, default: 0.3
            A scale factor to apply to the rgbFace color if `shadow_rgbFace`
            is ``None``.
        **kwargs
            Extra keywords are stored and passed through to
            :meth:`AbstractPathEffect._update_gc`.
        N)rK   r   _shadow_colorr[   r\   r]   r^   rR   )r	   r
   Zshadow_colorr`   ra   r7   )r/   r   r   r   %  s    zSimpleLineShadow.__init__c             C   s   |j  }|j| | jdkrT|j p&ddd \}}}	|| j || j |	| j f}
n| j}
|j|
 |j| j | j|| j	}|j
|||| j|  |j  dS )z
        Overrides the standard draw_path to add the shadow offset and
        necessary color changes for the shadow.
        N      ?rc   )ro   ro   ro   )rC   rS   rn   Zget_foregroundr^   re   rf   r]   r    rR   r$   r   rT   )r	   r   r   r%   r&   r'   rU   rg   rh   ri   r_   r   r   r   r$   C  s    


zSimpleLineShadow.draw_pathrj   rX   rj   )rp   r   rm   rm   )r)   r*   r+   r,   r   r$   rL   r   r   )r/   r   rl   "  s    rl   c                   s*   e Zd ZdZd fdd	Zdd Z  ZS )	PathPatchEffectza
    Draws a `.PathPatch` instance whose Path comes from the original
    PathEffect artist.
    r   c                s"   t  j|d tjg f|| _dS )a  
        Parameters
        ----------
        offset : pair of floats
            The offset to apply to the path, in points.
        **kwargs
            All keyword arguments are passed through to the
            :class:`~matplotlib.patches.PathPatch` constructor. The
            properties which cannot be overridden are "path", "clip_box"
            "transform" and "clip_path".
        )r
   N)rK   r   mpatchesZ	PathPatchpatch)r	   r
   r7   )r/   r   r   r   a  s    zPathPatchEffect.__init__c             C   sV   || j _| j j|| j|  | j j|j  |j }|rF| j j|  | j j| d S )N)	rs   _pathZset_transformr   Zset_clip_boxZget_clip_rectangleZget_clip_pathZset_clip_pathZdraw)r	   r   r   r%   r&   r'   Z	clip_pathr   r   r   r$   p  s    zPathPatchEffect.draw_pathr   r   )ru   )r)   r*   r+   r,   r   r$   rL   r   r   )r/   r   rq   [  s   rq   N)r,   Zmatplotlib.backend_basesr   Z
matplotlibr   r[   r   rr   r   r   r   r"   rJ   rP   rQ   Z
withStrokerW   ZwithSimplePatchShadowrl   rq   r   r   r   r   <module>   s   7W	
B
9