B
    }d/B              
   @   s   d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZ ddlmZ ddlZd	d
lmZ d	dlmZ d	dlmZ dZddddddddddg
ZG dd deZe	e G dd deZG dd deZdS )z Plotting utilities for segments
    )allow_rasterization)is_color_like)	FormatterMultipleLocator)register_projection)PatchCollection)	RectangleN   )Axes)tint)	to_stringz(Duncan Macleod <duncan.macleod@ligo.org>/\|-+xoO.*c                   s   e Zd ZdZdZ fddZdd Z fddZd"ddZd#ddZ	d$ddZ
d%ddZdd Zd&ddZd'ddZdd ZeeeejdZe fd d!Zejje_  ZS )(SegmentAxesa  Custom `Axes` to display segments.

    This `SegmentAxes` provides custom methods for displaying any of

    - `~gwpy.segments.DataQualityFlag`
    - `~gwpy.segments.Segment` or :class:`ligo.segments.segment`
    - `~gwpy.segments.SegmentList` or :class:`ligo.segments.segmentlist`
    - `~gwpy.segments.SegmentListDict` or
      :class:`ligo.segments.segmentlistdict`

    Parameters
    ----------
    insetlabels : `bool`, default: `False`
        display segment labels inside the axes. Prevents very long segment
        names from getting squeezed off the end of a standard figure

    See also
    --------
    gwpy.plot.Axes
        for documentation of other args and kwargs
    segmentsc                sJ   | dd | dd t j|| | jt  t }| j| d S )NZxscalezauto-gpsinsetlabelsF)
setdefaultsuper__init__ZyaxisZset_major_locatorr   SegmentFormatterZset_major_formatter)selfargskwargs	formatter)	__class__ _/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/gwpy/plot/segments.pyr   A   s    zSegmentAxes.__init__c             C   s|   ddl m}m} t||r | jS t||r0| jS t|tj jrD| jS t|tj j	rX| j
S tdt| j dt|j d S )N   )DataQualityFlagDataQualityDictz	no known z.plot_xxx method for )r   r&   r'   
isinstance	plot_dict	plot_flagligosegmentlistdictplot_segmentlistdictsegmentlistplot_segmentlist	TypeErrortype__name__)r   objr&   r'   r#   r#   r$   _plot_methodP   s    

zSegmentAxes._plot_methodc                s   g }t |}xR|r^y| |d }W n tk
r:   P Y nX |||d f| |d qW |rx|t j|| | jdddd |S )a  Plot data onto these axes

        Parameters
        ----------
        args
            a single instance of

                - `~gwpy.segments.DataQualityFlag`
                - `~gwpy.segments.Segment`
                - `~gwpy.segments.SegmentList`
                - `~gwpy.segments.SegmentListDict`

            or equivalent types upstream from :mod:`ligo.segments`

        kwargs
            keyword arguments applicable to `~matplotib.axes.Axes.plot`

        Returns
        -------
        Line2D
            the `~matplotlib.lines.Line2D` for this line layer

        See also
        --------
        matplotlib.axes.Axes.plot
            for a full description of acceptable ``*args` and ``**kwargs``
        r   NbothF)enableaxistight)	listr4   r0   appendpopextendr   plot	autoscale)r   r   r    outZplotter)r"   r#   r$   r=   `   s    zSegmentAxes.plotkeyr   c             K   sd   g }xZ|  D ]N\}}| dkr*|j}n| dkr:|}|| j|ft||d| qW |S )aI  Plot a `~gwpy.segments.DataQualityDict` onto these axes

        Parameters
        ----------
        flags : `~gwpy.segments.DataQualityDict`
            data-quality dict to display

        label : `str`, optional
            labelling system to use, or fixed label for all `DataQualityFlags`.
            Special values include

            - ``'key'``: use the key of the `DataQualityDict`,
            - ``'name'``: use the :attr:`~DataQualityFlag.name` of the
              `DataQualityFlag`

            If anything else, that fixed label will be used for all lines.

        known : `str`, `dict`, `None`, default: '/'
            display `known` segments with the given hatching, or give a
            dict of keyword arguments to pass to
            :meth:`~SegmentAxes.plot_segmentlist`, or `None` to hide.

        **kwargs
            any other keyword arguments acceptable for
            `~matplotlib.patches.Rectangle`

        Returns
        -------
        collection : `~matplotlib.patches.PatchCollection`
            list of `~matplotlib.patches.Rectangle` patches
        namer@   )labelknown)itemslowerrA   r:   r*   r   )r   flagsrB   rC   r    r?   Zlabflagr#   r#   r$   r)      s     zSegmentAxes.plot_dictNc             K   s4  |dkr|   }|jr0|dd |dd n|dd |dd |d}|d|jpb|j}|dd | j|jf||d	|}|d
kr0| d ddd}t	|t
r|| nV|dkr|j|ddd d n4|tkr|jd|d n|jd||ddd d | j|jf||d	| |S )a  Plot a `~gwpy.segments.DataQualityFlag` onto these axes.

        Parameters
        ----------
        flag : `~gwpy.segments.DataQualityFlag`
            Data-quality flag to display.

        y : `float`, optional
            Y-axis value for new segments.

        height : `float`, optional,
            Height for each segment, default: `0.8`.

        known : `str`, `dict`, `None`
            One of the following

            - ``'fancy'`` - to use fancy format (try it and see)
            - ``'x'`` (or similar) - to use hatching
            - `str` to specify ``facecolor`` for known segmentlist
            - `dict` of kwargs to use
            - `None` to ignore known segmentlist

        **kwargs
            Any other keyword arguments acceptable for
            `~matplotlib.patches.Rectangle`.

        Returns
        -------
        collection : `~matplotlib.patches.PatchCollection`
            list of `~matplotlib.patches.Rectangle` patches for active
            segments
        N	facecolorz#33cc33rC   z#ff0000rB   zorderr   )yrB   )NFignorei)rH   
collectionrI   fancyheightg?g?)rN   F)fillZhatchTg      ?)rO   rH   rN   )
get_next_yZisgoodr   r;   rB   rA   r/   activeZget_facecolorr(   dictupdategetHATCHESrC   )r   rG   rJ   r    rC   rA   collZknown_kwr#   r#   r$   r*      s4    "



zSegmentAxes.plot_flag皙?Tc                s   d dd t r0dt dd dkr@|   fdd	|D }|rt||d
dd}	|	| |dk|	_|	_	| 
|	}
|dkr|	 }|	t| n:g }
x4|D ],}|| || d}|
| | qW | jdddd |
S )a5  Plot a `~gwpy.segments.SegmentList` onto these axes

        Parameters
        ----------
        segmentlist : `~gwpy.segments.SegmentList`
            list of segments to display

        y : `float`, optional
            y-axis value for new segments

        collection : `bool`, default: `True`
            add all patches as a
            `~matplotlib.collections.PatchCollection`, doesn't seem
            to work for hatched rectangles

        label : `str`, optional
            custom descriptive name to print as y-axis tick label

        **kwargs
            any other keyword arguments acceptable for
            `~matplotlib.patches.Rectangle`

        Returns
        -------
        collection : `~matplotlib.patches.PatchCollection`
            list of `~matplotlib.patches.Rectangle` patches
        rH   colorz#629fca	edgecolorg      ?)factorNc                s$   g | ]}t |f d qS ))rN   rH   )SegmentRectangle).0seg)rH   rN   r    rJ   r#   r$   
<listcomp>%  s   z0SegmentAxes.plot_segmentlist.<locals>.<listcomp>rI   r	   )Zmatch_originalrI   rK    r5   F)r6   r7   r8   )r;   r   r   r   rP   r   rT   Zset_rasterized_ignore_yposZadd_collection	get_labelZ	set_labelr   r:   Z	add_patchr>   )r   r.   rJ   rN   rB   rL   Z
rasterizedr    patchesrV   r?   patchr#   )rH   rN   r    rJ   r$   r/      s2    





zSegmentAxes.plot_segmentlistr	   c             K   sT   |dkr|   }g }x:| D ].\}}|| j|f||d| ||7 }qW |S )aI  Plot a `~gwpy.segments.SegmentListDict` onto
        these axes

        Parameters
        ----------
        segmentlistdict : `~gwpy.segments.SegmentListDict`
            (name, `~gwpy.segments.SegmentList`) dict

        y : `float`, optional
            starting y-axis value for new segmentlists

        **kwargs
            any other keyword arguments acceptable for
            `~matplotlib.patches.Rectangle`

        Returns
        -------
        collections : `list`
            list of `~matplotlib.patches.PatchCollection` sets for
            each segmentlist
        N)rJ   rB   )rP   rD   r:   r/   )r   r,   rJ   Zdyr    collectionsrA   r.   r#   r#   r$   r-   @  s    z SegmentAxes.plot_segmentlistdictc             C   s   t | jddS )zFind the next y-axis value at which a segment list can be placed

        This method simply counts the number of independent segmentlists or
        flags that have been plotted onto these axes.
        F)rK   )lenget_collections)r   r#   r#   r$   rP   _  s    zSegmentAxes.get_next_yc                s"    dkr| j S  fdd| j D S )a  Return the collections matching the given `_ignore` value

        Parameters
        ----------
        ignore : `bool`, or `None`
            value of `_ignore` to match

        Returns
        -------
        collections : `list`
            if `ignore=None`, simply returns all collections, otherwise
            returns those collections matching the `ignore` parameter
        Nc                s    g | ]}t |d d kr|qS )r`   N)getattr)r\   c)rK   r#   r$   r^   w  s    z/SegmentAxes.get_collections.<locals>.<listcomp>)re   )r   rK   r#   )rK   r$   rg   g  s    zSegmentAxes.get_collectionsc             C   s   |dkr| j  n|| _ dS )zSet the labels to be inset or not

        Parameters
        ----------
        inset : `bool`, `None`
            if `None`, toggle the inset state, otherwise set the labels to
            be inset (`True) or not (`False`)
        N)_insetlabels)r   Zinsetr#   r#   r$   set_insetlabelsz  s    
zSegmentAxes.set_insetlabelsc             C   s   | j S )z'Returns the inset labels state
        )rj   )r   r#   r#   r$   get_insetlabels  s    zSegmentAxes.get_insetlabels)fgetfsetdocc          	      s   x|    D ]}|  rl| |_| |_| |_|	d |
d| d f |dddd q|  dkry||j W n tk
r   Y qX |	|j |
|j |`|`|`qW t j||S )	Nleftg{Gz?r	   g      ?whitenone)alpharH   rY   F)Z	get_yaxisZget_ticklabelsrl   Zget_bbox_patchZ
_orig_bboxZget_haZ_orig_haZget_positionZ	_orig_posZset_horizontalalignmentZset_positionZset_bboxAttributeErrorr   draw)r   r   r    Ztick)r"   r#   r$   ru     s(    



zSegmentAxes.draw)r@   r   )N)NrW   NTN)Nr	   )N)N)r2   
__module____qualname____doc__rA   r   r4   r=   r)   r*   r/   r-   rP   rg   rk   rl   propertyr   r   ru   r
   __classcell__r#   r#   )r"   r$   r   )   s$   *
*
J 
A



r   c               @   s   e Zd ZdZdddZdS )r   z0Custom tick formatter for y-axis flag names
    Nc             C   sx   x*| j jjddD ]}||jkr| S qW xF| j jjD ]8}| r8| dkrRq8|tjj|	 j
 kr8| S q8W dS )NF)rK   Z
_nolegend_r_   )r7   axesrg   ra   rb   rc   r+   r   segmentZget_bboxZ	intervaly)r   tposrV   rd   r#   r#   r$   __call__  s    
zSegmentFormatter.__call__)N)r2   rv   rw   rx   r   r#   r#   r#   r$   r     s   r   c                   s   e Zd Zd fdd	Z  ZS )r[   皙?centerc                s   |  dkr|}n8|  dkr,||d  }n|  dkrB|| }ntd|d |d  }t j|d |ff||d| || _d	S )
a  Build a `~matplotlib.patches.Rectangle` from a segment

        Parameters
        ----------
        segment : `~gwpy.segments.Segment`
            ``[start, stop)`` GPS segment

        y : `float`
            y-axis position for segment

        height : `float`, optional, default: 1
            height (in y-axis units) for segment

        valign : `str`
            alignment of segment on y-axis value:
                `top`, `center`, or `bottom`

        **kwargs
            any other keyword arguments acceptable for
            `~matplotlib.patches.Rectangle`

        Returns
        -------
        box : `~matplotlib.patches.Rectangle`
            rectangle patch for segment display
        bottom)r   Zcentreg       @topz2valign must be one of 'top', 'center', or 'bottom'r	   r   )widthrN   N)rE   
ValueErrorr   r   r|   )r   r|   rJ   rN   Zvalignr    Zy0r   )r"   r#   r$   r     s    
zSegmentRectangle.__init__)r   r   )r2   rv   rw   r   rz   r#   r#   )r"   r$   r[     s   r[   )rx   Zmatplotlib.artistr   Zmatplotlib.colorsr   Zmatplotlib.tickerr   r   Zmatplotlib.projectionsr   Zmatplotlib.collectionsr   Zmatplotlib.patchesr   Zligo.segmentsr+   r{   r
   colorsr   textr   
__author__rU   r   r   r[   r#   r#   r#   r$   <module>   s&      	