U
    f»{jÞq ã                   @   s  d 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	Z	ddl
Z
ddlZddl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 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m Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; ddl<m=Z= dddddddddddœ
Z>edd„ ƒZ?dÁd!d"„Z@dÂd$d%„ZAdÃd&d'„ZBdÄd)d*„ZCd+d,„ ZDdÅd.d/„ZEd0d1d2gd3fd4d5„ZFed6d7„ ƒZGdÆd8d9„ZHdÇd:d;„ZIdÈd<d=„ZJdÉd@dA„ZKdÊdBdC„ZLdDdE„ ZMdFdG„ ZNe0dd#dHejOdIdfdJdK„ƒZPdLdM„ ZQdNdO„ ZRdPdQ„ ZSdRdS„ ZTG dTdU„ dUeUƒZVdËdYdZ„ZWdÌd[d\„ZXd]d^„ ZYdÍd_d`„ZZe0dÎdbdc„ƒZ[ddde„ Z\dfdg„ Z]dÏdhdi„Z^dÐdjdk„Z_dÑdldm„Z`dÒdndo„ZaG dpdq„ dqeUƒZbdrds„ ZcG dtdu„ duƒZddÓdvdw„ZedÔdydz„ZfdÕd}d~„ZgG dd€„ d€eUƒZhdÖd‚dƒ„Zid„d…„ Zjd×d†d‡„Zkdˆd‰„ ZldØdŠd‹„ZmdŒd�„ ZndÙd�d�„Zod‘d’„ ZpdÚd˜d™„Zqe5dšd›„ ƒZrdÛd�dž„ZsdŸd „ Ztd¡d¢„ Zud£d¤„ ZvdÜd§d¨„Zwd©dª„ Zxd«d¬„ ZydÝd®d¯„Zzd°d±„ Z{dÞd´dµ„Z|dßd·d¸„Z}d¹dº„ Z~d»d¼„ Zd½d¾„ Z€d¿dÀ„ Z�dS )àz*Utility functions for plotting M/EEG data.é    )Údefaultdict)Úcontextmanager)ÚdatetimeN)Úpartial)Ú	decoratoré   )Ú_handle_default)Ú	_get_args)Ú	show_fiffÚInfo)ÚFIFF)Úcreate_info)Úchannel_typeÚchannel_indices_by_typeÚpick_channelsÚ_pick_data_channelsÚ_DATA_CH_TYPES_SPLITÚ_DATA_CH_TYPES_ORDER_DEFAULTÚ_VALID_CHANNEL_TYPESÚ	pick_infoÚ_picks_by_typeÚpick_channels_covÚ_contains_ch_type)Ú
setup_projÚ
Projection)Úcompute_rank)ÚverboseÚ
get_configÚ_check_ch_locsÚ_check_optionÚloggerÚfill_docÚ_plÚ_check_sphereÚ_ensure_intÚ_validate_typeÚ_to_rgbÚwarn)Úapply_transzEEG channelZGradiometerZMagnetometerzsEEG channelzDBS channelzEOG channelz
ECG sensorz
EMG sensorzECoG channelzmiscellaneous sensor)
ZeegÚgradÚmagZseegZdbsZeogZecgZemgZecogÚmiscc                 O   s4   z| ||ŽW S  t k
r.   tjtjd� Y nX dS )z4Protect against Qt exiting on event-handling errors.)ÚfileN)Ú	ExceptionÚ	tracebackÚ	print_excÚsysÚstderr)ZfunÚargsÚkwargs© r4   úL/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/viz/utils.pyÚ
safe_event8   s    r6   Fc                 C   sê   d}|dkrL|dkrLt  | ¡ ¡ }|r*dn| }|dkr¶t  | ¡dk r¶d}njt|ƒr^|| ƒ}n4|dkr’|rndnt  | ¡}|dkr’t  | ¡dk r’d}t|ƒr¤|| ƒ}n|dkr¶t  | ¡}|râd}||t  | ¡dœ}t|jf |Žtƒ ||fS )aü  Handle vmin and vmax parameters for visualizing topomaps.

    For the normal use-case (when `vmin` and `vmax` are None), the parameter
    `norm` drives the computation. When norm=False, data is supposed to come
    from a mag and the output tuple (vmin, vmax) is symmetric range
    (-x, x) where x is the max(abs(data)). When norm=True (a.k.a. data is the
    L2 norm of a gradiometer pair) the output tuple corresponds to (0, x).

    Otherwise, vmin and vmax are callables that drive the operation.
    FNç        r   Tzb_setup_vmin_vmax output a (min={vmin}, max={vmax}) range whereas the minimum of data is {data_min})ÚvminÚvmaxZdata_min)ÚnpÚabsÚmaxÚminÚcallabler'   ÚformatÚUserWarning)Údatar8   r9   ÚnormZshould_warnZwarn_msgZwarn_valr4   r4   r5   Ú_setup_vmin_vmaxA   s*    


rC   Tc                 K   s^   ddl m} ddlm} t|dƒr8t|jdƒr8|jj}n|ƒ }| rZ|dkrZ|pP|jf |Ž dS )a  Show a figure while suppressing warnings.

    Parameters
    ----------
    show : bool
        Show the figure.
    fig : instance of Figure | None
        If non-None, use fig.show().
    **kwargs : dict
        Extra arguments for :func:`matplotlib.pyplot.show`.
    r   N)Úget_backendÚmneÚbackendZagg)Úmatplotlib.pyplotÚpyplotÚ
matplotlibrD   ÚhasattrrE   rF   Úshow)rK   Úfigr3   ÚpltrD   rF   r4   r4   r5   Úplt_showi   s    
rN   c                 K   sŒ   ddl m} t|tdƒ |ƒ }t dd¡ ¡ dkr6d}|dkrTt| fd|i|—Ž n4d	d
lm	} ddl
m} | rx| ¡  |rˆ|| ¡ ƒ dS )ax  Show the browser considering different backends.

    Parameters
    ----------
    show : bool
        Show the figure.
    block : bool
        If to block execution on showing.
    fig : instance of Figure | None
        Needs to be passed for Qt backend,
        optional for matplotlib.
    **kwargs : dict
        Extra arguments for :func:`matplotlib.pyplot.show`.
    é   )Úget_browser_backendÚblockZ_MNE_BROWSER_NO_BLOCKÚfalseÚtrueFrI   r   )ÚQApplication)Ú_qt_app_execN)Ú_figurerP   r%   ÚboolÚosÚgetenvÚlowerrN   Zqtpy.QtWidgetsrT   Zbackends._utilsrU   rK   Úinstance)rK   rQ   rL   r3   rP   rF   rT   rU   r4   r4   r5   Ú_show_browser   s    r\   ç333333ó?c           
      C   s6  t | ddƒ ddlm} |dkr(| ¡ n|}|j ¡  | ¡ }t| ||d�}|rTdS z(tj	dd��}|j
f |Ž W 5 Q R X W nt tk
rð   z>tj	dd��(}t|dƒr´|jd|Ž n
| |¡ W 5 Q R X W n  tk
rê   td
ƒ Y Y dS X Y nX |D ]:}t|dƒ�rt|jƒn| ¡ }	|	 d¡söt|	|jdƒ qödS )aÏ  Adjust subplot parameters to give specified padding.

    .. note:: For plotting please use this function instead of
              ``plt.tight_layout``.

    Parameters
    ----------
    pad : float
        Padding between the figure edge and the edges of subplots, as a
        fraction of the font-size.
    h_pad : float
        Padding height between edges of adjacent subplots.
        Defaults to ``pad_inches``.
    w_pad : float
        Padding width between edges of adjacent subplots.
        Defaults to ``pad_inches``.
    fig : instance of Figure
        Figure to apply changes to.

    Notes
    -----
    This will not force constrained_layout=False if the figure was created
    with that method.
    ÚnumericÚpadr   N)r_   Úh_padÚw_padT)ÚrecordÚset_layout_engineÚtightzQMatplotlib function "tight_layout" is not supported. Skipping subplot adjustment.ÚmessagezThis figure includes AxesrI   )rd   )r%   rG   rH   ZgcfÚcanvasÚdrawZget_constrained_layoutÚdictÚwarningsÚcatch_warningsÚtight_layoutr-   rJ   rc   Zset_tight_layoutr'   Ústrre   Zget_messageÚ
startswithÚcategory)
r_   r`   ra   rL   rM   Zconstrainedr3   ÚwsÚwZw_msgr4   r4   r5   rk       s0    


rk   c                 C   sJ   | j dks"tdd„ | jd D ƒƒr,tdƒ‚nt| jd ƒdk rFtdƒ‚dS )	z!Handle interactive SSP selection.Tc                 s   s   | ]}|d  V  qdS )ÚactiveNr4   ©Ú.0Úpr4   r4   r5   Ú	<genexpr>Ù   s     z%_check_delayed_ssp.<locals>.<genexpr>ÚprojszMProjs are already applied. Please initialize the data with proj set to False.rO   zNo projs found in evoked.N)ÚprojÚallÚinfoÚRuntimeErrorÚlen)Ú	containerr4   r4   r5   Ú_check_delayed_sspÖ   s    
ÿ
r}   Úaxesc                    sâ   ddl m‰  t| tttjf|ƒ t| tjƒrN| jdkrNt	d|› d| j› d�ƒ‚t 
‡ fdd„| D ƒ¡d }t|ƒr t|› d	|› d
|d › dt| |d  ƒ› �ƒ‚|dk	rÞt|ddd�}t| ƒ|krÞt	|› d|› dt| ƒ› �ƒ‚dS )z/Validate whether input is a list/array of axes.r   ©ÚAxesrO   zif zP is a numpy array, it must be one-dimensional, but the received numpy array has z< dimensions. Try using ravel or flatten method of the array.c                    s   g | ]}t |ˆ ƒ ‘qS r4   )Ú
isinstance©rs   Úxr   r4   r5   Ú
<listcomp>é   s     z-_validate_if_list_of_axes.<locals>.<listcomp>z7 must be an array-like of matplotlib axes objects, but ú[z] is of type NÚobligatory_lenzif not None©Úextraz! must be an array-like of length z, but the length is )Zmatplotlib.axesr€   r%   ÚlistÚtupler:   Úndarrayr�   ÚndimÚ
ValueErrorÚwherer{   Ú	TypeErrorÚtyper$   )r~   r†   ÚnameZ	wrong_idxr4   r   r5   Ú_validate_if_list_of_axesà   s&    ÿ(ÿÿÿr’   é   é
   é   Úvtkc           	         s4  t jˆ dd�‰ tˆ ƒdkr.tˆ ƒdkr.tdƒ‚tˆ ƒdkrNtˆ dk ƒrNtdƒ‚tt  ˆ ¡dkƒrhtd	ƒ‚|d
k�rddlm} tˆ ƒdkr¶t  t  	ˆ ¡ ˆ f¡ˆ d  dˆ d   ‰ n"ˆ t  
ˆ ¡ t  ˆ t  
ˆ ¡ ¡ ‰ ˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddffˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddffˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddffˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddfˆ d ddffdœ}| d|¡S |dk�rtˆ ƒdk�rNt  t  	ˆ ¡ dgˆ f¡ˆ d  ‰ n6t  ˆ dd… dgˆ dd… f¡‰ ˆ t  t  ˆ ¡¡ ‰ t  dddddddg¡}t  dddddddg¡}t  dddddddg¡}t  dddddddg¡}t  d¡d d ‰t j‡ ‡fdd„||||fD ƒ j}|S tdt|ƒ› �ƒ‚dS )aB  Return a colormap similar to that used by mne_analyze.

    Parameters
    ----------
    limits : list (or array) of length 3 or 6
        Bounds for the colormap, which will be mirrored across zero if length
        3, or completely specified (and potentially asymmetric) if length 6.
    format : str
        Type of colormap to return. If 'matplotlib', will return a
        matplotlib.colors.LinearSegmentedColormap. If 'vtk', will
        return an RGBA array of shape (256, 4).

    Returns
    -------
    cmap : instance of colormap | array
        A teal->blue->gray->red->yellow colormap. See docstring of the 'format'
        argument for further details.

    Notes
    -----
    For this will return a colormap that will display correctly for data
    that are scaled by the plotting function to span [-fmax, fmax].
    Úfloat©Zdtypeé   é   z limits must have 3 or 6 elementsr7   z.if 3 elements, limits must all be non-negativer   z'limits must be monotonically increasingrI   )Úcolorséÿÿÿÿr   rO   ç      à?é   ç      ð?r“   )ÚredÚgreenÚblueÚalphaZmne_analyze)r–   ZmayaviNé   é€   g      `@c                    s   g | ]}t  ˆˆ d | ¡‘qS )éÿ   )r:   Úinterp©rs   Úc©ÚlimitsZxpr4   r5   r„   G  s   ÿz(mne_analyze_colormap.<locals>.<listcomp>z-format must be either matplotlib or vtk, got )r:   Úasarrayr{   r�   ÚanyÚdiffrI   r›   ÚconcatenateZflipudr=   r<   ZLinearSegmentedColormapr;   ÚarrayÚarangeZr_ÚTÚrepr)	r«   r?   r›   ZcdictÚrÚgÚbÚaZcolormapr4   rª   r5   Úmne_analyze_colormap÷   s†    
ÿ
ÿÿûûûûî
ÿ"
ÿ
ÿr¸   c                 c   s   d| _ z
d V  W 5 d| _ X d S )NFT)Zeventson)Úobjr4   r4   r5   Ú_events_offP  s    
rº   c              	   C   s  d|kr¸t |d  ¡ ƒ}|r‚t|ƒ gt|ƒ }t|d ƒ�@ tt||ƒƒD ]*\}\}}||krL|d  |¡ |||< qLW 5 Q R X tt||d ƒƒD ] \}\}}	|s”|	d r”d||< q”n| dd¡}
|
gt|d ƒ }d}d|krèd}nt	 
||d ¡süd}|dk�r|d ||ƒ d	S )
z+Perform operations when proj boxes clicked.Úproj_checksrv   rq   TÚ
apply_projFÚ
proj_boolsZplot_update_proj_callbackN)r‰   Z
get_statusrx   r{   rº   Ú	enumerateÚzipZ
set_activeÚgetr:   Zarray_equal)ÚeventÚparamsÚall_ZboolsZ	new_boolsZbiÚoldÚnewr¶   rt   rw   Zcompute_projr4   r4   r5   Ú_toggle_projY  s*    
rÆ   c                    sŒ   | dkr<t tƒ}tddg|dd…  ƒ}‡ fdd„|D ƒ} n,t| tjt tfƒshtd| › dt| ƒ› d	�ƒ‚ˆdk	r‚‡fd
d„| D ƒ} t | ¡S )zCDetermine channel plotting order for browse-style Raw/Epochs plots.Nr)   r*   r   c                    s*   g | ]"}t ˆ ƒD ]\}}||kr|‘qqS r4   )r¾   )rs   Z
order_typeÚpick_idxZ	pick_type)Úch_typesr4   r5   r„   ~  s
    
 þz/_get_channel_plotting_order.<locals>.<listcomp>z!order should be array-like; got "z" (z).c                    s   g | ]}|ˆ kr|‘qS r4   r4   ©rs   Úch©Úpicksr4   r5   r„   …  s      )	r‰   r   rŠ   r�   r:   r‹   r�   r�   r¬   )ÚorderrÈ   rÌ   Zch_type_orderr4   )rÈ   rÌ   r5   Ú_get_channel_plotting_orderx  s    rÎ   c           	         sì   ddl m} tˆtƒr ˆdkr$tƒ nˆ‰‡fdd„ˆ ¡ D ƒ‰ˆ dd¡‰ ˆ dkrVdn
‡ fdd„}t|ƒ}ˆ ¡ D ](\}}|dk r’td	|› d
�ƒ‚|||< qr|S ˆdkrØ|dkr¶tƒ nt	 
|dd…df ¡}|ˆ|ˆƒS t‡fdd„ƒS dS )z4Make or validate a dict mapping event ids to colors.rO   )Ú_handle_event_colorsNc                    s$   i | ]\}}t ˆ  ||¡d ƒ|“qS )zevent_color key)r$   rÀ   )rs   ÚkeyÚvalue)Úevent_idr4   r5   Ú
<dictcomp>Ž  s   ÿz*_make_event_color_dict.<locals>.<dictcomp>rœ   c                      s   ˆ S ©Nr4   r4   )Údefaultr4   r5   Ú<lambda>‘  ó    z(_make_event_color_dict.<locals>.<lambda>z>event_color keys must be strictly positive, or -1 (cannot use ú)r   c                      s   ˆ S rÔ   r4   r4   )Úevent_colorr4   r5   rÖ   �  r×   )r+   rÏ   r�   rh   ÚitemsÚpopr   ÚKeyErrorÚsetr:   Úunique)	rÙ   ÚeventsrÒ   rÏ   Údefault_factoryZnew_dictrÐ   rÑ   Zuniq_eventsr4   )rÕ   rÙ   rÒ   r5   Ú_make_event_color_dict‰  s$    

ÿ
$rá   ÚautoçÍÌÌÌÌÌô?c                 C   sô  ddl m} ddlm}	 | dkr*d }}n t|tƒrH| |krHd|  }}n‚|dkrx|dkrxt t | ¡¡}t 	| | ¡}nR|dkr�t 	| | ¡}n:|dkr¨t 	| | ¡}n"|| }
|
| k rÊt
d | ||¡ƒ‚|rÖ|d7 }|| }|tddd|  ƒ | t|ƒd	  }d }|	d
|d d|d  fd�}|||||d�}g }|�r€ttd| d || |ƒƒ}ttt|| ƒƒ| ƒd | d … }nt| ƒ}|D ]Z}tƒ }|dk�rÌ|�r¶|j|d d� |�rÌ|j|d d� | |j|| f|Ž¡ �qŒ||||fS )Nr   )ÚGridSpecrO   )rV   râ   z)Cannot plot {} axes in a {} by {} figure.çš™™™™™¹?rž   r�   Fç      ø?ç      Ð?)ÚtoolbarÚfigsize)ÚfigureÚheight_ratiosr   )Úsharex)Úsharey)Zmatplotlib.gridspecrä   Z_mpl_figurerV   r�   ÚintÚmathÚfloorÚsqrtÚceilr�   r?   r<   rW   rÝ   ÚrangeÚsortedrh   ÚupdateÚappendÚadd_subplot)Zn_cellsZncolsZnrowsÚtitleZcolorbarÚsizerì   rí   rä   rV   ZnaxesÚwidthÚheightrë   rL   Úgsr~   ÚexcludeZax_idxsZax_idxÚ
subplot_kwr4   r4   r5   Ú_prepare_trellis   sR    
  ÿ&&
rÿ   c                 C   sÖ  ddl m} |d }dd„ |D ƒ}|r4dd„ |D ƒn| d|d gt|ƒ ¡}td	td
d„ |D ƒƒd d gƒ}t|ƒd d d }t||fd�}	t|	dƒ d| }
|	|d< |	jd|
dd|
 fdd�}| d¡ |j	|||d�}|j
D ]}| d¡ | d¡ qæt|ƒD ]0\}}|d �r|j| D ]}| d¡ �q$�q| tt|d�¡ ||d< |	j dt¡ |	jddd|
fdd�}| |d¡}| tt|d d!�¡ ||d"< z|	j ¡  t|	dd#� W n tk
�rÐ   Y nX d$S )%z#Toggle options (projectors) dialog.r   )Úwidgetsrv   c                 S   s   g | ]}|d  ‘qS ©Údescr4   rr   r4   r4   r5   r„   Ø  s     z'_draw_proj_checkbox.<locals>.<listcomp>c                 S   s   g | ]}|d  ‘qS )rq   r4   rr   r4   r4   r5   r„   Ù  s     r½   r¼   g      @c                 S   s   g | ]}t |d  ƒ‘qS r  ©r{   rr   r4   r4   r5   r„   Ü  s     g      @r�   rO   ræ   ©ré   zSSP projection vectorsgUUUUUUÅ?Úfig_projgš™™™™™é?F)Zframeonz%Projectors marked with "X" are active)ÚlabelsÚactivesz0.5rŸ   rq   ú#ff0000)rÂ   r»   Úkey_press_eventz
Toggle allT)rÂ   rÃ   Úproj_all©rL   r'   N)rI   r   rÀ   r{   r<   Úfigure_nobarÚ_set_window_titleÚadd_axesÚ	set_titleZCheckButtonsZ
rectanglesÚset_edgecolorZset_linewidthr¾   ÚlinesZ	set_colorZ
on_clickedr   rÆ   rf   Úmpl_connectÚ
_key_pressZButtonrg   rN   r-   )rÁ   rÂ   Zdraw_current_stater   rv   r  r  rú   rû   r  ÚoffsetZax_tempr»   ÚrectÚiirt   rƒ   r
  r4   r4   r5   Ú_draw_proj_checkboxÒ  sD    ÿ"





r  c                 C   s6   t | tƒr2t | ¡r2tt| ƒƒt| ƒkr2t| dƒ} | S )Nr   )r�   r—   r:   Úisfiniterl   Úround©Úlabelr4   r4   r5   Ú_simplify_float  s
    ÿ
r  c                  C   s0   t dƒ} | dk	r,|  d¡} tdd„ | D ƒƒ} | S )z2Get default / most recent figure size from config.ZMNE_BROWSE_RAW_SIZENú,c                 S   s   g | ]}t |ƒ‘qS r4   )r—   )rs   Úsr4   r4   r5   r„     s     z,_get_figsize_from_config.<locals>.<listcomp>)r   ÚsplitrŠ   r  r4   r4   r5   Ú_get_figsize_from_config  s
    
r   z    é   c              	   C   s˜   t | t|||d�}t |t|||d�}	t ¡  ||	| |¡}
|dk	rLt|dƒ}ntjdddd�}|j}|�}| 	|
 
d¡¡ W 5 Q R X |dkr”t |¡ |S )	a€  Compare the contents of two fiff files using diff and show_fiff.

    Parameters
    ----------
    fname_1 : str
        First file to compare.
    fname_2 : str
        Second file to compare.
    fname_out : str | None
        Filename to store the resulting diff. If None, a temporary
        file will be created.
    show : bool
        If True, show the resulting diff in a new tab in a web browser.
    indent : str
        How to indent the lines.
    read_limit : int
        Max number of bytes of data to read from a tag. Can be np.inf
        to always read all data (helps test read completion).
    max_str : int
        Max number of characters of string representation to print for
        each tag's data.
    %(verbose)s

    Returns
    -------
    fname_out : str
        The filename used for storing the diff. Could be useful for
        when a temporary file is used.
    )ÚoutputÚindentÚ
read_limitÚmax_strNÚwbFz.html)ÚdeleteÚsuffixzutf-8T)r
   r‰   ÚdifflibZHtmlDiffÚ	make_fileÚopenÚtempfileÚNamedTemporaryFiler‘   ÚwriteÚencodeÚ
webbrowserZopen_new_tab)Zfname_1Zfname_2Z	fname_outrK   r#  r$  r%  r   Zfile_1Zfile_2r®   ÚfZfidr4   r4   r5   Úcompare_fiff  s$      ÿ ÿ
r2  c               	   O   sn   ddl m}m} |d }zFd|d< |j| |Ž}t|jjjd  ¡ ƒ}|D ]}|jj |¡ qHW 5 ||d< X |S )a@  Make matplotlib figure with no toolbar.

    Parameters
    ----------
    *args : list
        Arguments to pass to :func:`matplotlib.pyplot.figure`.
    **kwargs : dict
        Keyword arguments to pass to :func:`matplotlib.pyplot.figure`.

    Returns
    -------
    fig : instance of Figure
        The figure.
    r   )ÚrcParamsrH   rè   Únoner	  )	rI   r3  rH   rê   r‰   rf   Ú	callbacksÚkeysÚ
disconnect)r2   r3   r3  rM   Zold_valrL   ZcbsrÐ   r4   r4   r5   r  G  s    
r  c           
      C   sÖ   t |dƒ dd„ t|  ¡  d¡| ¡  d¡ƒD ƒ}|j|ddd�}| d¡ | d	¡ | ¡  | ¡  	¡ D ]$\\}}}	|	 
d ¡ |d
krjd|	_qj|j dt¡ |rÒz|j ¡  t|dd� W n tk
rÐ   Y nX d S )NZHelpc                 S   s   g | ]\}}||g‘qS r4   r4   )rs   Úc1Úc2r4   r4   r5   r„   f  s     z"_show_help_fig.<locals>.<listcomp>Ú
ÚcenterÚleft)ZcellTextÚlocZcellLocFé   r   Úrightr	  r  )r  r¿   Ústripr  ÚtableZauto_set_font_sizeZset_fontsizeZset_axis_offZ	get_celldrÚ   r  Z_locrf   r  r  rg   rN   r-   )
Úcol1Úcol2Úfig_helpÚaxrK   ZcelltextrA  ÚrowÚcolÚcellr4   r4   r5   Ú_show_help_figd  s&    
ÿ



rI  c                 C   s0   t ||fdd�}| d¡}t| |||dd� d S )NéP   )ré   Údpiéo   T)rK   )r  r÷   rI  )rB  rC  rú   rû   rD  rE  r4   r4   r5   Ú
_show_help~  s    
rM  c                 C   s(   ddl m} | jdkr$| | jj¡ dS )zHandle key press in dialog.r   NÚescape)rG   rH   rÐ   Úcloserf   rê   )rÁ   rM   r4   r4   r5   r  „  s    
r  c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚClickableImagea¨  Display an image so you can click on it and store x/y positions.

    Takes as input an image array (can be any array that works with imshow,
    but will work best with images.  Displays the image and lets you
    click on it.  Stores the xy coordinates of each click, so now you can
    superimpose something on top of it.

    Upon clicking, the x/y coordinate of the cursor will be stored in
    self.coords, which is a list of (x, y) tuples.

    Parameters
    ----------
    imdata : ndarray
        The image that you wish to click on for 2-d points.
    **kwargs : dict
        Keyword arguments. Passed to ax.imshow.

    Notes
    -----
    .. versionadded:: 0.9.0
    c                 K   s    ddl m} g | _|| _| ¡ | _| j d¡| _| jjd | _	| jjd | _
| jj|fd| j
d| j	fddœ|—Ž| _| j d¡ | jj d| j¡ tdd	� dS )
zDisplay the image for clicking.r   NrL  rO   T)ÚextentÚpickerÚoffÚ
pick_event©rQ   )rG   rH   ÚcoordsÚimdatarê   rL   r÷   rE  ÚshapeÚymaxÚxmaxÚimshowÚimÚaxisrf   r  ÚonclickrN   )ÚselfrW  r3   rM   r4   r4   r5   Ú__init__¢  s     

þþzClickableImage.__init__c                 C   s   |j }| j |j|jf¡ dS )z¶Handle Mouse clicks.

        Parameters
        ----------
        event : matplotlib.backend_bases.Event
            The matplotlib object that we use to get x/y position.
        N)Ú
mouseeventrV  rö   ÚxdataÚydata)r_  rÁ   ra  r4   r4   r5   r^  ²  s    zClickableImage.onclickc                 K   sà   ddl m} t| jƒdkr"tdƒ‚| ¡ \}}|j| jfdd| jd| j	fi|—Ž | 
¡ | ¡ g\}}t| jŽ \}}|j||dd� t t| jƒ¡ t¡}	t|	| jƒD ]\}
}|j|
|ddd� q¦| |¡ | |¡ tƒ  dS )	z¼Plot the x/y positions stored in self.coords.

        Parameters
        ----------
        **kwargs : dict
            Arguments are passed to imshow in displaying the bg image.
        r   NzKNo coordinates found, make sure you click on the image that is first shown.rQ  r  )r©   é   )ZfontsizeÚcolor)rG   rH   r{   rV  r�   Úsubplotsr[  rW  rZ  rY  Úget_xlimÚget_ylimr¿   Úscatterr:   r±   Úastyperl   ZannotateÚset_xlimÚset_ylimrN   )r_  r3   rM   r1  rE  ÚxlimÚylimZxcoordsZycoordsZann_textÚtxtZcoordr4   r4   r5   Úplot_clicks½  s    $

zClickableImage.plot_clicksc                 K   s2   ddl m} t | j¡}||fd| ji|—Ž}|S )aE  Turn coordinates into an MNE Layout object.

        Normalizes by the image you used to generate clicks

        Parameters
        ----------
        **kwargs : dict
            Arguments are passed to generate_2d_layout.

        Returns
        -------
        layout : instance of Layout
            The layout.
        r   )Úgenerate_2d_layoutZbg_image)Zchannels.layoutrq  r:   r°   rV  rW  )r_  r3   rq  rV  Últr4   r4   r5   Ú	to_layoutÕ  s    zClickableImage.to_layoutN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r`  r^  rp  rs  r4   r4   r4   r5   rP  ‹  s
   rP  rE  rO   Úpressc           	      C   s¬   |dkr|j  |¡\}}n.|dkr4|j |¡\}}n|dks@t‚|\}}|dkrft| jj|||d�}n8|dkr„t| jj|||d�}n|dkržt| jj||d�}|d	d
� d	S )z-Fake a click at a relative point within axes.rE  rA   Zpixrx  )rƒ   ÚyÚbuttonÚreleaseZmotion)rƒ   ry  N)ZguiEvent)	Ú	transAxesZtransform_pointÚ	transDataÚAssertionErrorr   rf   Úbutton_press_eventÚbutton_release_eventÚmotion_notify_event)	rL   rE  ÚpointZxformrz  Úkindrƒ   ry  Úfuncr4   r4   r5   Ú_fake_clickê  s    ÿr…  c                 C   s\   |dkrdS |dk	r*| j D ]}| |¡ q| jddddgdd�}|j|dd� | d¡ |S )	aT  Add a background image to a plot.

    Adds the image specified in ``im`` to the
    figure ``fig``. This is generally meant to
    be done with topo plots, though it could work
    for any plot.

    .. note:: This modifies the figure and/or axes in place.

    Parameters
    ----------
    fig : Figure
        The figure you wish to add a bg image to.
    im : array, shape (M, N, {3, 4})
        A background image for the figure. This must be a valid input to
        `matplotlib.pyplot.imshow`. Defaults to None.
    set_ratios : None | str
        Set the aspect ratio of any axes in fig
        to the value in set_ratios. Defaults to None,
        which does nothing to axes.

    Returns
    -------
    ax_im : instance of Axes
        Axes created corresponding to the image you added.

    Notes
    -----
    .. versionadded:: 0.9.0
    Nr   rO   Ú
backgroundr  râ   ©Úaspectrœ   )r~   Z
set_aspectr  r[  Ú
set_zorder)rL   r\  Z
set_ratiosrE  Zax_imr4   r4   r5   Úadd_background_imageý  s    

rŠ  c                 C   s¢   ddl m} | jjdd�}t| jƒd }|dk r4d}|||dd�d }t|ƒ|krxt || ¡| d… }t || ¡}| j| }t|ƒdkrž| j| 	¡  g}|S )zaFind peaks from evoked data.

    Returns ``npeaks`` biggest peaks as a list of time points.
    r   )Ú	argrelmax©r]  r!  rO   )rÍ   r]  N)
Zscipy.signalr‹  rA   Ústdr{   Útimesr:   ZargsortÚsortÚargmax)ÚevokedZnpeaksr‹  ÚgfprÍ   ÚpeaksZmax_indicesrŽ  r4   r4   r5   Ú_find_peaks)  s    
r”  c                 C   sæ   t |tƒrš|dkrd\}}|dkrN|dkrBt|r4dndt| jƒƒ}t| |ƒ}qª|dkr�|dkrtt|rhdnd	t|ƒƒ}t | jd
 | jd |¡}qªtdƒ‚nt 	|¡rª|g}t 
|t¡}|jdkrÎtd|j ƒ‚t|ƒdkrâtdƒ |S )z$Return a list of times for topomaps.Úinteractive)r“  rO   r“  Nr™   é   râ   r“   r”   r   rœ   z{Got an unrecognized method for `times`. Only 'peaks', 'auto' and 'interactive' are supported (or directly passing numbers).rO   z#times must be 1D, got %d dimensionsé   z?More than 25 topomaps plots requested. This might take a while.)r�   rl   r=   r{   rŽ  r”  r:   Úlinspacer�   Zisscalarr°   r—   rŒ   r'   )ÚinstZ	use_timesZn_peaksÚfewr4   r4   r5   Ú_process_times=  s,    



ÿr›  Útopomapc           +         sì  ddl m} td|dddgƒ tˆtƒs:tdtˆƒ› �ƒ‚tˆƒ}t}|dkrt|D ]}t	ˆ|ƒrR|} qjqR|| ‰nN|d	kršt
ƒ ‰|D ]}ˆ|| 7 ‰q†n(||kr¬|| ‰ntd
|› d|› d�ƒ‚tˆƒdkrÞtd|› d�ƒ‚tˆˆd�sòtdƒ‚ˆd }‡fdd„ˆD ƒ}t t|ƒdf¡}t|ƒD ]\\}}|d dd… ||< |d tjk�r&|dk�rntdƒ t d¡}t||| ƒ||< �q&~t dd„ |D ƒ¡}‡fdd„t|ƒD ƒ‰ |dk�ràtdƒ‰‡ ‡‡fdd„tˆƒD ƒ‰�n´|dk�rædd lm}m}m}m} |d!k�r&|ˆd"d#�}t
| ¡ ƒ}n>t
ƒ t
ƒ  }}|| D ]&}tˆd$ ||ˆd%�ƒ}|  |¡ �q<t !t|ƒdf¡}t|ƒD ]d\}} ‡fd&d„| D ƒ}!t|!ƒdk�rª�q~||! j"\}"}#}$tj#||"|#|$ƒdd'�}%|%||dd…f< �q~n:ddl$m%‰ t &ddt|ƒ¡‰‡‡fd(d„t't|ƒƒD ƒ}t|tj(t
fƒ�s>td)| ƒ‚t )tˆƒdf¡‰tˆƒD ]:\}&}'t|ƒD ]&\}(})|'|)k�rh||( ˆ|&<  �qX�qh�qX|dk�r¦d*| n|}t*|ˆˆˆˆ |||||	||||
||d+�}*|dk�rè|*|*j+j,fS |*S ),a¥  Plot sensors positions.

    Parameters
    ----------
    %(info_not_none)s
    kind : str
        Whether to plot the sensors as 3d, topomap or as an interactive
        sensor selection dialog. Available options 'topomap', '3d', 'select'.
        If 'select', a set of channels can be selected interactively by using
        lasso selector or clicking while holding control key. The selected
        channels are returned along with the figure instance. Defaults to
        'topomap'.
    ch_type : None | str
        The channel type to plot. Available options 'mag', 'grad', 'eeg',
        'seeg', 'dbs', 'ecog', 'all'. If ``'all'``, all the available mag,
        grad, eeg, seeg, dbs and ecog channels are plotted. If None (default),
        then channels are chosen in the order given above.
    title : str | None
        Title for the figure. If None (default), equals to
        ``'Sensor positions (%%s)' %% ch_type``.
    show_names : bool | array of str
        Whether to display all channel names. If an array, only the channel
        names in the array are shown. Defaults to False.
    ch_groups : 'position' | array of shape (n_ch_groups, n_picks) | None
        Channel groups for coloring the sensors. If None (default), default
        coloring scheme is used. If 'position', the sensors are divided
        into 8 regions. See ``order`` kwarg of :func:`mne.viz.plot_raw`. If
        array, the channels are divided by picks given in the array.

        .. versionadded:: 0.13.0
    to_sphere : bool
        Whether to project the 3d locations to a sphere. When False, the
        sensor array appears similar as to looking downwards straight above the
        subject's head. Has no effect when kind='3d'. Defaults to True.

        .. versionadded:: 0.14.0
    axes : instance of Axes | instance of Axes3D | None
        Axes to draw the sensors to. If ``kind='3d'``, axes must be an instance
        of Axes3D. If None (default), a new axes will be created.

        .. versionadded:: 0.13.0
    block : bool
        Whether to halt program execution until the figure is closed. Defaults
        to False.

        .. versionadded:: 0.13.0
    show : bool
        Show figure if True. Defaults to True.
    %(sphere_topomap_auto)s
    pointsize : float | None
        The size of the points. If None (default), will bet set to 75 if
        ``kind='3d'``, or 25 otherwise.
    linewidth : float
        The width of the outline. If 0, the outline will not be drawn.
    %(verbose)s

    Returns
    -------
    fig : instance of Figure
        Figure containing the sensor topography.
    selection : list
        A list of selected channels. Only returned if ``kind=='select'``.

    See Also
    --------
    mne.viz.plot_layout

    Notes
    -----
    This function plots the sensor locations from the info structure using
    matplotlib. For drawing the sensors using PyVista see
    :func:`mne.viz.plot_alignment`.

    .. versionadded:: 0.12.0
    rO   )Ú_rgbrƒ  rœ  Ú3dÚselectz%info must be an instance of Info not Nrx   zch_type must be one of z not ú!r   z$Could not find any channels of type Ú.)ry   rÌ   z No valid channel positions foundÚ
dev_head_tc                    s   g | ]}ˆ d  | ‘qS ©Úchsr4   ©rs   Úpick©ry   r4   r5   r„   Ê  s     z plot_sensors.<locals>.<listcomp>r™   r=  Zcoord_framez^dev_head_t is None, transforming MEG sensors to head coordinate frame using identity transformrž   c                 S   s   g | ]}|d  ‘qS )Úch_namer4   rÉ   r4   r4   r5   r„   Ö  s     c                    s    g | ]\}}|ˆ d  kr|‘qS )Úbadsr4   )rs   Úidxr‘   r§  r4   r5   r„   ×  s      re  c                    s*   g | ]"\}}|ˆ krd nˆt ˆ|ƒ ‘qS )r    )r   )rs   Úir¦  )r©  Ú
def_colorsry   r4   r5   r„   Ú  s   ÿ)ÚpositionÚ	selectionr   )Úread_vectorview_selectionÚ_SELECTIONSÚ_EEG_SELECTIONSÚ_divide_to_regionsr­  F)Zadd_stimÚch_namesr§  c                    s*   g | ]"}|ˆ krt  ˆ |k¡d  d  ‘qS ©r   )r:   rŽ   rÉ   rË   r4   r5   r„   î  s    ÿrŒ  c                    s   g | ]}ˆj  ˆ | ¡‘qS r4   )ÚcmZjet©rs   r«  )r›   rM   r4   r5   r„   ø  s     zEch_groups must be None, 'position', 'selection', or an array. Got %s.zSensor positions (%s))Ú	pointsizeÚ	linewidth)-r‘  r�  r   r�   r   r�   r�   r   r   r   r‰   r�   r{   r   rz   r:   Úemptyr¾   r   ZFIFFV_COORD_DEVICEr'   Úeyer(   r°   r   Úchannelsr¯  r°  r±  r²  Úvaluesr   rö   Úonesr²   ÚmeanrG   rH   r˜  ró   r‹   ÚzerosÚ_plot_sensorsÚlassor®  )+ry   rƒ  Úch_typerø   Ú
show_namesZ	ch_groupsÚ	to_spherer~   rQ   rK   Úspherer·  r¸  r   r�  Z
ch_indicesZallowed_typesÚ	this_typer¢  r¤  ÚposÚcirÊ   r³  r¯  r°  r±  r²  Z
color_valsr®  r»  rª  Zch_groupZcolor_picksrƒ   ry  Úzre  rÇ   r¦  ÚindrÑ   rL   r4   )r©  r›   r¬  ry   rÌ   rM   r5   Úplot_sensors]  s¶    P



ÿ


ÿ



þÿ
      ý
rË  c           	      C   sÀ   | j j|krdS | j jdkrB|jdk	rB| jD ]}|j |¡ q,dS |rJdS | jd }|| }|| }|jd  ¡  t|ƒdkrœ| 	|d |d |d |¡ n| 	|d |d |¡ |j
 ¡  dS )zPick a channel in plot_sensors.NÚcontrolr   r™   rO   r   )ra  ÚinaxesrÐ   rÁ  rÊ  Ú
select_oneÚtextsÚremover{   Útextrf   rg   )	rÁ   rL   rE  rÇ  r³  rÃ  rÊ  r¨  Úthis_posr4   r4   r5   Ú_onpick_sensor  s     

rÓ  c                 C   s   t |ddƒdk	r|j ¡  dS )z&Listen for sensor plotter close event.rÁ  N)ÚgetattrrÁ  r7  )rÁ   rL   r4   r4   r5   Ú_close_event'  s    rÕ  c           )   
      s   ddl m} ddlm} ddlm} ddlm}m} t	||ƒ}t
 |d t|ƒ¡}d||< |dk}|r¤tƒ }|
d	kr€|jd	d
� |jdt|d ƒfd |d�\}}n| ¡ }|
d	k�rJ|dkrÂdn|}|jdddddd� |j| dd…df | dd…df | dd…df d||||d� d|_d|_|j d¡ |j d¡ |j d¡ nÂ|dk�rXdn|}|jddddd� |||||d�\} }|||ƒ |j| dd…df | dd…df dd||||d�}|
dk�rØt||ˆ ƒ|_nd|_|jdd� |�r|jddddd� | d¡ ~d}|�r>t|t t
j!fƒ�r>‡ fd d!„|D ƒ}nt"t| ƒƒ}|D ]^}| | }|
d	k�r†| |d |d |d ˆ | ¡ n$|j|d d" |d ˆ | d#d$d%� �qN|
dk}| #¡ j$\}} }!}"|j% &¡ ‰‡fd&d!„|j'D ƒ}#t
 (d'd!„ |#D ƒ¡}$t
 )|$|!k¡d }%t|%ƒ�r>|$|% |!  ¡ |! }&|jdd(|&  d)� |�rft*t+||| ˆ |d*�}'|j% ,d+|'¡ |�rvt-||ƒ t*t.|d,�}(|j% ,d-|(¡ t/|	|d.� |S )/zPlot sensors.r   ©r3  N)ÚAxes3DrO   )Ú_get_pos_outlinesÚ_draw_outlineszaxes.edgecolorr    rž  )Z
projectionzfigure.figsizer   )ré   rþ   éK   Ú )ÚzorderT)rR  r©   r  Z	edgecolorr¸  éZ   zx (m)zy (m)zz (m)r—  )rÄ  F)rR  Úclip_onr©   Ú
edgecolorsr  ÚlwrŸ  Úequalr‡  )r<  Úbottomr?  ÚtoprS  c                    s   g | ]}t ˆ ƒ |¡‘qS r4   )r‰   Úindex)rs   r‘   ©r³  r4   r5   r„   i  s     z!_plot_sensors.<locals>.<listcomp>g{®Gázd?r<  r;  )ZhaÚvac                    s   g | ]}|j ˆ d �‘qS )©Úrenderer)Úget_window_extentr‚   rç  r4   r5   r„   w  s     c                 S   s   g | ]}|j d  ‘qS r´  )r<   r‚   r4   r4   r5   r„   x  s     çš™™™™™ñ?©r?  )rL   rE  rÇ  r³  rÃ  rT  )rL   Zclose_eventrU  )0rI   r3  rG   rH   Zmpl_toolkits.mplot3dr×  rœ  rØ  rÙ  r#   r:   Úrepeatr{   rh   rõ   rf  r<   Z
get_figurerÑ  ri  ZazimZelevZxaxisZset_label_textÚyaxisZzaxisÚSelectFromCollectionrÁ  rÝ   Zsubplots_adjustr]  r�   r‰   r‹   ró   ré  Zboundsrf   Zget_rendererrÏ  r°   Únonzeror   rÓ  r  r  rÕ  rN   ))rÇ  ry   rÌ   r›   r©  r³  rø   rÃ  rE  rK   rƒ  rQ   rÄ  rÅ  r·  r¸  r3  rM   r×  rØ  rÙ  rß  Zaxes_was_nonerþ   rL   ZoutlinesZptsZconnect_pickerÚindicesrª  rÒ  ÚxminÚyminrZ  rY  ZextentsZxmaxsZbad_xmax_ixsZneeded_spacerR  Úclosedr4   )r³  rè  r5   rÀ  -  sª    
 þ
2  ÿÿ

$  þ


" ÿ



 ÿ
rÀ  c              
      s2  ddl m} ddlm} tdˆƒ‰tˆ ||fƒs8tdƒ‚ˆ ¡ D ]V\}}t|tƒrZ|dks@zt	|ƒˆ|< W q@ t
k
r”   td|›d|›d	�ƒ‚Y q@X q@t‡fd
d„ˆ jdd�D ƒƒrºˆS tˆ jƒ}dd„ | ¡ D ƒ}ˆ jdk�rötˆ |ƒ�rŽdtˆ jƒd  }	t |	dˆ j¡}	|	t	ˆ jd ƒ }
t ˆ j¡}t ||
d  ˆ j ¡ d¡}t ||
d  dˆ j ¡ ¡}‡ fdd„||fD ƒ\}}ˆ  ||¡}nftˆ |ƒ�rüdtˆ jƒtˆ jƒ d  }tt |dtˆ ƒ¡ƒ}tj ttˆ ƒƒ|d¡}ˆ  ¡ |  ¡ ‰ nˆ j }tˆ |ƒ�r&ˆ j  !dd¡ "tˆ jƒdg¡}ˆ ¡ D ]þ\}}||k�s.|dk�rN�q.|||  }|�rä|j#d ˆ jd  |k�rät|ˆ jd  ƒ}|dd…d|j#d | | …f }|j#}|j$ "d||d ¡}|t %|d¡8 }|j$ "|¡}| &¡ }|t '|¡ }|j(�rt )t *|ddg¡¡d }nd}|ˆ|< �q.ˆS )a7  Compute scalings for each channel type automatically.

    Parameters
    ----------
    scalings : dict
        The scalings for each channel type. If any values are
        'auto', this will automatically compute a reasonable
        scaling for that channel type. Any values that aren't
        'auto' will not be changed.
    inst : instance of Raw or Epochs
        The data for which you want to compute scalings. If data
        is not preloaded, this will read a subset of times / epochs
        up to 100mb in size in order to compute scalings.
    remove_dc : bool
        Whether to remove the mean (DC) before calculating the scalings. If
        True, the mean will be computed and subtracted for short epochs in
        order to compensate not only for global mean offset, but also for slow
        drifts in the signals.
    duration : float
        If remove_dc is True, the mean will be computed and subtracted on
        segments of length ``duration`` seconds.

    Returns
    -------
    scalings : dict
        A scalings dictionary with updated values
    r   )ÚBaseRaw)Ú
BaseEpochsZscalings_plot_rawz Must supply either Raw or Epochsrâ   z/scalings must be "auto" or float, got scalings[z]=z& which could not be converted to floatc                    s   g | ]}ˆ | d k‘qS )râ   r4   )rs   rÂ  )Úscalingsr4   r5   r„   º  s   ÿz%_compute_scalings.<locals>.<listcomp>T)rÞ   c                 S   s"   i | ]\}}t |ƒd kr||“qS r´  r  )rs   Zi_typeZi_ixsr4   r4   r5   rÓ   À  s    ÿ z%_compute_scalings.<locals>.<dictcomp>Fg    „×—Aé   rO   Úsfreqç       @Nc                    s"   g | ]}t t|ˆ jd   ƒƒ‘qS )rø  )rî   r  ry   r‚   ©r™  r4   r5   r„   Ì  s    r   rœ   r—  rÚ  rŸ   )+Zio.baserô  Zepochsrõ  r   r�   r�   rÚ   rl   r—   r-   rx   Úget_channel_typesr   ry   Zpreloadr{   r³  r:   ZclipÚn_timesr¾  rŽ  r=   r<   Z_read_segmentrî   ÚrandomÚchoiceró   ÚcopyZ	load_dataÚ_dataZswapaxesÚreshaperX  r²   ZnanmeanZravelr  rù   r®   Z
percentile)rö  r™  Z	remove_dcÚdurationrô  rõ  rÐ   rÑ   rÈ   rü  Zn_secsZtime_middleZtminZtmaxZsminZsmaxrA   Zn_epochsZ
ixs_epochsZ	this_dataÚlengthrX  Ziqrr4   )r™  rö  r5   Ú_compute_scalingsŠ  sz    
ÿ

ÿÿ
ÿ
ÿ
 "r  c                 C   sP   | dkr|rdnddf} n2t | tƒsL| dkr8|r4dnd} | |dkrFdndf} | S )zSet color map interactivity.r•  ZRedsÚRdBu_rTNr   F)r�   rŠ   )ÚcmapZn_axesrB   r4   r4   r5   Ú_setup_cmapð  s    
r  c                    sl   ddl m‰  ˆ j|d�}| d¡}| d ‰‡ ‡fdd„t| ƒD ƒ}ˆ  dd	ˆd
  dˆd
  ¡}||||fS )a0  Prepare axes for topomaps and colorbar in joint plot figure.

    Parameters
    ----------
    n_maps: int
        Number of topomaps to include in the figure
    figsize: tuple
        Figure size, see plt.figsize

    Returns
    -------
    fig : matplotlib.figure.Figure
        Figure with initialized axes
    main_ax: matplotlib.axes._subplots.AxesSubplot
        Axes in which to put the main plot
    map_ax: list
        List of axes for each topomap
    cbar_ax: matplotlib.axes._subplots.AxesSubplot
        Axes for colorbar next to topomaps
    r   Nr  éÔ   r   c                    s"   g | ]}ˆ   d ˆ|d ˆ ¡‘qS )rž   r   )Úsubplotr‚   ©rM   Útsr4   r5   r„     s     z'_prepare_joint_axes.<locals>.<listcomp>rž   r“   rO   r”   )rG   rH   rê   r÷   ró   r	  )Zn_mapsré   rL   Zmain_axZmap_axZcbar_axr4   r
  r5   Ú_prepare_joint_axesû  s    
r  c                   @   sP   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d„ Z
dd„ ZdS )ÚDraggableColorbarz~Enable interactive colorbar.

    See http://www.ster.kuleuven.be/~pieterd/python/html/plotting/interactive_colorbar.html
    c                    sˆ   dd l m‰  || _|| _d | _t‡ fdd„tˆ jƒD ƒƒ| _|  j| 	¡ j
g7  _| j | 	¡ j
¡| _| jjj| jjjf| _|  ¡  d S )Nr   c                    s"   g | ]}t tˆ j|ƒd ƒr|‘qS )ÚN)rJ   rÔ  rµ  r¶  ©rM   r4   r5   r„   (  s    ÿz.DraggableColorbar.__init__.<locals>.<listcomp>)rG   rH   ÚcbarÚmappablerx  rô   Údirrµ  ÚcycleZget_cmapr‘   rä  rB   r8   r9   ÚlimsÚconnect)r_  r  r  r4   r  r5   r`  #  s    zDraggableColorbar.__init__c                 C   s|   | j jjj d| j¡| _| j jjj d| j¡| _| j jjj d| j	¡| _
| j jjj d| j¡| _| j jjj d| j¡| _dS )z"Connect to all the events we need.r  r€  r�  r	  Zscroll_eventN)r  rE  rê   rf   r  Úon_pressÚcidpressÚ
on_releaseÚ
cidreleaseÚ	on_motionÚ	cidmotionÚ	key_pressZkeypressÚ	on_scrollÚscroll©r_  r4   r4   r5   r  /  s(     ÿ ÿ ÿ ÿ ÿzDraggableColorbar.connectc                 C   s   |j | jjkrdS |j| _dS )zHandle button press.N)rÍ  r  rE  ry  rx  ©r_  rÁ   r4   r4   r5   r  <  s    zDraggableColorbar.on_pressc                 C   sø  | j jj| j jj }d}|jdkr4|  jd7  _�nR|jdkrP|  jd8  _�n6|jdkr~| jd | j j_| jd | j j_�n|jdkr¾| j j j|| d 8  _| j j j|| d 7  _nÈ|jd	krþ| j j j|| d 8  _| j j j|| d 7  _nˆ|jd
k�r@| j j j|| d 8  _| j j j|| d 8  _nF|jdk�r‚| j j j|| d 8  _| j j j|| d 8  _ndS | jdk �r¤t| jƒd | _n| jt| jƒk�r¼d| _| j| j }| j j	 
|¡ t| j ƒ | j	 
|¡ |  ¡  dS )zHandle key press.ç¸…ëQ¸ž?ZdownrO   Úupú r   ú+rœ   ú-ZpageupZpagedownN)r  rB   r9   r8   rÐ   rä  r  r{   r  r  Zset_cmapÚ_draw_without_renderingÚ_update)r_  rÁ   ÚscaleÚpercr  r4   r4   r5   r  B  s>    





zDraggableColorbar.key_pressc                 C   sò   | j dkrdS |j| jjkr dS | j }|j| }|j| _ | jjj| jjj }d}|jdkrœ| jj j|| t	 
|¡ 8  _| jj j|| t	 
|¡ 8  _nJ|jdkræ| jj j|| t	 
|¡ 8  _| jj j|| t	 
|¡ 7  _|  ¡  dS )zHandle mouse movements.Nr!  rO   r™   )rx  rÍ  r  rE  ry  rB   r9   r8   rz  r:   Úsignr'  )r_  rÁ   ZyprevÚdyr(  r)  r4   r4   r5   r  f  s     


 "
  zDraggableColorbar.on_motionc                 C   s   d| _ |  ¡  dS ©zHandle release.N)rx  r'  r   r4   r4   r5   r  y  s    zDraggableColorbar.on_releasec                 C   sB   |j dk rdnd}| jj j|9  _| jj j|9  _|  ¡  dS )zHandle scroll.r   rê  g]tÑEí?N)Ústepr  rB   r8   r9   r'  )r_  rÁ   r(  r4   r4   r5   r  ~  s    zDraggableColorbar.on_scrollc                 C   sR   ddl m} | j |ƒ ¡ | j ¡  t| jƒ | j | jj¡ | jj	j
j ¡  d S )Nr   )ÚAutoLocator)Úmatplotlib.tickerr.  r  Z	set_ticksZupdate_ticksr&  r  Zset_normrB   rE  rê   rf   rg   )r_  r.  r4   r4   r5   r'  …  s    

zDraggableColorbar._updateN)rt  ru  rv  rw  r`  r  r  r  r  r  r  r'  r4   r4   r4   r5   r    s   $r  c                 C   s0   z| j jj}W n tk
r(   | j}Y nX |ƒ S rÔ   )rE  rê   Zdraw_without_renderingÚAttributeErrorZdraw_all)r  Úmethr4   r4   r5   r&  Ž  s
    r&  c                   @   sJ   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dS )rî  aŠ  Select channels from a matplotlib collection using ``LassoSelector``.

    Selected channels are saved in the ``selection`` attribute. This tool
    highlights selected points by fading other points out (i.e., reducing their
    alpha values).

    Parameters
    ----------
    ax : instance of Axes
        Axes to interact with.
    collection : instance of matplotlib collection
        Collection you want to select from.
    alpha_other : 0 <= float <= 1
        To highlight a selection, this tool sets all selected points to an
        alpha value of 1 and non-selected points to ``alpha_other``.
        Defaults to 0.3.
    linewidth_other : float
        Linewidth to use for non-selected sensors. Default is 1.

    Notes
    -----
    This tool selects collection objects based on their *origins*
    (i.e., ``offsets``). Calls all callbacks in self.callbacks when selection
    is ready.
    r�   rO   c           
      C   sD  ddl m} |jj| _|| _|| _|| _|| _|| _|| _	| 
¡ | _t| jƒ| _| ¡ | _| ¡ | _| ¡ | _t| jƒdkr†tdƒ‚nFt| jƒdkrÌt | j| j¡ | jd¡| _t | j| j¡ | jd¡| _| j| jd d …df< | j| jd d …df< t | j| j¡| _tdtddd	�ƒ}	||fd
| ji|	—Ž| _tƒ | _tƒ | _d S )Nr   )ÚLassoSelectorz Collection must have a facecolorrO   rœ   Úliner    r�   )re  r¸  Zonselect) Úmatplotlib.widgetsr2  rê   rf   Ú
collectionr³  Úalpha_otherÚlinewidth_otherÚalpha_selectedÚlinewidth_selectedZget_offsetsÚxysr{   ZNptsZget_facecolorsÚfcZget_edgecolorsÚecZget_linewidthsrà  r�   r:   Ztiler  ÚfullÚ_prop_kwrh   Ú	on_selectrÁ  r‰   r®  r5  )
r_  rE  r5  r³  r6  r7  r8  r9  r2  Zline_kwr4   r4   r5   r`  ²  s2    





zSelectFromCollection.__init__c                    sÀ   ddl m} t|ƒdkrdS ||ƒ‰ t ‡ fdd„ˆjD ƒ¡d }ˆjjdkrŒ‡fdd„ˆjD ƒ}t	|ƒt	|ƒ }t
| t	|ƒt	|ƒ ¡ƒ}t ˆj¡|  ¡ ˆjdd…< ˆ |¡ ˆ ¡  dS )	z$Select a subset from the collection.r   )ÚPathr™   Nc                    s   g | ]}ˆ   |¡‘qS r4   )Zcontains_point)rs   Zxy)Úpathr4   r5   r„   Ù  s     z2SelectFromCollection.on_select.<locals>.<listcomp>rÌ  c                    s$   g | ]}t  ˆ j|k¡d  d  ‘qS r´  )r:   rŽ   r³  r¨   r  r4   r5   r„   Û  s     )Zmatplotlib.pathr@  r{   r:   rï  r:  rf   Ú_keyr®  rÝ   r‰   Úunionr°   r³  ÚtolistÚstyle_sensorsÚnotify)r_  Zvertsr@  ÚindsZselsZintersr4   )rA  r_  r5   r?  Ò  s    
zSelectFromCollection.on_selectc                 C   sh   | j | }|| jkr.| j |¡}| j |¡ n| j |¡ t | j | j¡ ¡ d }|  |¡ |  	¡  dS )zSelect or deselect one sensor.r   N)
r³  r®  rä  rÛ   rö   r:   Zin1drï  rE  rF  )r_  rÊ  r¨  Zsel_indrG  r4   r4   r5   rÎ  ã  s    


zSelectFromCollection.select_onec                 C   s   | j D ]
}|ƒ  qdS )z0Notify listeners that a selection has been made.N)r5  )r_  Úcallbackr4   r4   r5   rF  ï  s    
zSelectFromCollection.notifyc                 C   s,   t  | j¡|  ¡ | jdd…< |  |¡ dS )z>Select many sensors using indices (for predefined selections).N)r:   r°   r³  rD  r®  rE  ©r_  rG  r4   r4   r5   Úselect_manyô  s    z SelectFromCollection.select_manyc                 C   s    | j | jdd…df< | j d | jdd…df< | j| jdd…< | j| j|df< | j| j|df< | j| j|< | j | j¡ | j 	| j¡ | j 
| j¡ | j ¡  dS )z#Style selected sensors as "active".Nrœ   r   )r6  r;  r<  r7  rà  r8  r9  r5  Úset_facecolorsÚset_edgecolorsZset_linewidthsrf   Ú	draw_idlerI  r4   r4   r5   rE  ù  s    z"SelectFromCollection.style_sensorsc                 C   s\   | j  ¡  | j| jdd…df< | j| jdd…df< | j | j¡ | j | j¡ | j 	¡  dS )zDisconnect the lasso selector.Nrœ   )
rÁ  Zdisconnect_eventsr8  r;  r<  r5  rK  rL  rf   rM  r  r4   r4   r5   r7    s    
zSelectFromCollection.disconnectN)r�   r�   rO   rO   )rt  ru  rv  rw  r`  r?  rÎ  rF  rJ  rE  r7  r4   r4   r4   r5   rî  —  s         ÿ
 rî  c                 C   sf   ddl m} | d¡}|s&| d¡}n| ¡ d }dD ]}| r6||kr6| |¡  qVq6| rb||fS |S )a  Get the current color list from matplotlib rcParams.

    Parameters
    ----------
    annotations : boolean
        Has no influence on the function if false. If true, check if color
        "red" (#ff0000) is in the cycle and remove it.

    Returns
    -------
    colors : list
    r   rÖ  zaxes.prop_cyclezaxes.color_cyclere  )z#fa8174z#d62728r  )rI   r3  rÀ   Úby_keyrÐ  )Úannotationsr3  Zcolor_cycler›   r    r4   r4   r5   Ú_get_color_list  s    

rP  r4   c                 C   s¸   |j |j }t t || k¡d t |j |k¡d ¡}t |t |j|k¡d ¡}t ||¡}tt |j | |j|  |¡ƒ}t	t |j | | ¡ƒ}	||	 }
| 
|¡ | |	|
|¡ dS )zHandle drawn annotations.r   N)Úonsetr  r:   Zintersect1drŽ   ÚdescriptionZ	setdiff1dr<   rö   r=   r'  )ÚstartÚstoprR  rO  ÚcurrentZendsrª  Znew_idxÚendrQ  r  r4   r4   r5   Ú_merge_annotations6  s"    ÿÿÿÿ
rW  rŸ   r|  c                 C   s�   ddl m} |j}|j ¡ }| |j ddg¡¡\}	}
| |j | dg¡¡\}}| t||ƒ d|g¡¡\}}||	|f|
|f|ddddd	d
d�	S )zÈConnect source and target plots with a line.

    Connect source and target plots with a line, such as time series
    (source) and topolots (target). Primarily used for plot_joint
    functions.
    r   )ÚLine2Dr�   r7   Zgreyr%  ræ   g…ëQ¸å?rO   F)Ú	transformre  Ú	linestyler¸  r£   rÜ  rÞ  )Zmatplotlib.linesrX  ZtransFigureÚinvertedrY  r|  r}  rÔ  )rƒ   rL   ZsourceaxZtargetaxry  Zy_source_transformrX  Z	trans_figZtrans_fig_invZxtZytZxsÚ_Zysr4   r4   r5   Ú_connection_lineF  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 )ÚDraggableLinezõCustom matplotlib line for moving around by drag and drop.

    Parameters
    ----------
    line : instance of matplotlib Line2D
        Line to add interactivity to.
    callback : function
        Callback to call when line is released.
    c                 C   sl   || _ d | _| ¡ d | _|| _|| _| j jj d| j	¡| _
| j jj d| j¡| _| j jj d| j¡| _d S )Nr   r  r€  r�  )r3  rx  Ú	get_xdataÚx0Úmodify_callbackÚdrag_callbackrê   rf   r  r  r  r  r  r  r  )r_  r3  ra  rb  r4   r4   r5   r`  g  s"    
 ÿ
 ÿ
 ÿzDraggableLine.__init__c                 C   s   | j  ||g¡ || _dS )zRepoisition the line.N)r3  Ú	set_xdatar`  )r_  rƒ   r4   r4   r5   Úset_xt  s    zDraggableLine.set_xc                 C   sL   |j | jjks| j |¡d s"dS | j ¡ }| j ¡ }|||j|jf| _dS )z)Store button press if on top of the line.r   N)	rÍ  r3  r~   Úcontainsr_  Z	get_ydatarb  rc  rx  )r_  rÁ   r`  Úy0r4   r4   r5   r  y  s
    

zDraggableLine.on_pressc                 C   sl   | j dkrdS |j| jjkr dS | j \}}}}|j| }| j || ¡ |  || d ¡ | jjj 	¡  dS )zMove the line on drag.Nr   )
rx  rÍ  r3  r~   rb  rc  rb  rê   rf   rg   )r_  rÁ   r`  rf  ZxpressZypressZdxr4   r4   r5   r  �  s    

zDraggableLine.on_motionc                 C   sL   |j | jjks| jdkrdS d| _| jjj ¡  |  | j|j	¡ |j	| _dS r,  )
rÍ  r3  r~   rx  rê   rf   rg   ra  r`  rb  r   r4   r4   r5   r  �  s    zDraggableLine.on_releasec                 C   sD   | j jj | j¡ | j jj | j¡ | j jj | j¡ | j  ¡  dS )zRemove the line.N)r3  rê   rf   Zmpl_disconnectr  r  r  rÐ  r  r4   r4   r5   rÐ  –  s    zDraggableLine.removeN)
rt  ru  rv  rw  r`  rd  r  r  r  rÐ  r4   r4   r4   r5   r^  \  s   
	r^  r  c              	   C   sÞ  |r|dkr| j d  d¡ n| j d  d¡ |d kr:g n|}t|  ¡ t|dƒt|dƒƒ}t tt	dd„ |D ƒ| ƒƒ¡}t
|ƒdk �r,dd	„ }t ||g¡}||ƒ}t t || ¡¡}t t || ¡¡}|| || g}t t |¡¡t t |¡¡ }tj||fžŽ }t t||d
 |d g ƒ¡}|  |¡ t|  ¡ ||ƒ}|  |¡ |�rŽ|	�rŽ| j d j|d
dg Ž  | j d j|d
dg Ž  n‚|�rÄt |  ¡ ¡}|  ¡ d |d< | j d j|Ž  nL|	�rt |  ¡ ¡}|�rð|  ¡ d
 |d
< n|  ¡ d |d< | j d j|Ž  |
�r@|  dgt
|ƒ ¡ |  dgt
|ƒ ¡ n*|d k	�rX| j|dd� |  d|› d�¡ |�r”|  ¡ \}}| j|||ddddd� |�r¢|  ¡  | jdd� | jdd� | j d  d¡ | j d  d
¡ d S )Nr7   rã  ÚzeroFr   c                 S   s   g | ]}|‘qS r4   r4   r‚   r4   r4   r5   r„   ¬  s     z$_setup_ax_spines.<locals>.<listcomp>c                 S   s0   t  t  | ¡¡}t  | ¡dt  |¡|dk    S )Nr”   r   )r:   Úlog10r;   r*  Zfix)ZtvalÚexpr4   r4   r5   Úlog_fix®  s    z!_setup_ax_spines.<locals>.log_fixr   rœ   râ  r<  rO   rÛ  rÝ  )ZrotationzTime (rØ   ú--ÚkrŸ   )Z
linestylesr›   r¸  rÜ  Úout)Ú	directionrë  r?  ) ZspinesZset_positionZset_visibleÚ_trim_ticksZ
get_xticksr  r:   r°   rô   rÝ   r{   Zargminr;   r�  r*  r®   r<   r±   Z
set_xticksZ
get_yticksÚ
set_yticksZ
set_boundsrg  rh  Zset_yticklabelsZset_xticklabelsZ
set_ylabelÚ
set_xlabelÚvlinesZinvert_yaxisZtick_paramsr‰  )r~   rr  rñ  rZ  rò  rY  Zinvert_yÚunitZtruncate_xaxisZtruncate_yaxisZskip_axlabelÚhlineÚ	time_unitZxticksrj  ZxlimsZ
temp_ticksZ
closer_idxZfurther_idxZ
start_stopr-  ZttsZyticksZxboundsZyboundsZ_yminZ_ymaxr4   r4   r5   Ú_setup_ax_spinesž  sd      


 ÿrv  c              	   C   sâ   ddl m} ddlm} t|tƒrš|dkrš| d dkr>| d n| d }t||dkrZ| d n|ƒ}|  ¡ � || d< W 5 Q R X tt	| d |d  d	 ƒd
ƒ}||ddd�}|dkr¾t
d|f ƒ‚|| |dƒd }t| dd�}||fS )z$Handle decim parameter for plotters.r   )Ú_check_decim)r$   râ   ÚlowpassNrø  r™   g�íµ ÷Æ°>rO   Údecimzan int or "auto")Zmust_ber   z2decim must be "auto" or a positive integer, got %sr4   )rý   )Zutils.mixinrw  Úutilsr$   r�   rl   r=   Ú_unlockr<   rî   r�   r   )ry   ry  rx  rw  r$   ZlpÚ
data_picksr4   r4   r5   Ú_handle_decimå  s     
ÿr}  c                    sZ  ddl m} t tˆ d ƒ¡}g }|d k	�r:|�r:tˆ ddd�}‡ fdd„|D ƒ}	tˆ d	 ƒ}
t|d
 ƒtˆ d ƒ@ t|d	 ƒ }||
 }tˆ d |ƒ}tˆ |ƒ}t	||gƒd d }||||dd�\}}|t 
|¡9 }t|ƒ|ksèt‚||||d d …tjf f< |	}|	|
|B  }t|ƒdk�rRtˆ d |ƒ}tj||< n|�rRtˆ ddd�\}}||fS )Nr   )Úcompute_whitenerr³  Fr4   ©Zwith_ref_megrý   c                    s   h | ]}ˆ d  | ’qS rå  r4   r¥  r§  r4   r5   Ú	<setcomp>  s     z(_setup_plot_projector.<locals>.<setcomp>r©  ÚnamesrO   r   )Úrankr   )Zadd_eeg_refr   )Úcovr~  r:   rº  r{   r   rÝ   r   r   Ú_triage_rank_sssrñ   r~  ZnewaxisÚnanr   )ry   Ú	noise_covrw   Zuse_noise_covÚnaver~  Z	projectorZwhitened_ch_namesr|  Z
data_namesZ	bad_namesZ	cov_namesZwhiten_namesZwhiten_picksZwhiten_infor‚  ZwhitenerZ	nan_namesZ	nan_picksr\  r4   r§  r5   Ú_setup_plot_projectorø  s>    
ÿ
   ÿ
rˆ  c                    sV   ‡ fdd„t D ƒ}d|ko d|k}|oJtˆ d ƒdkoJˆ d d  d¡dk	}|||fS )	zCheck SSS history in info.c                    s   g | ]}t ˆ |ƒr|‘qS r4   )r   rÉ   r§  r4   r5   r„   &  s    
ÿz_check_sss.<locals>.<listcomp>r*   r)   Zproc_historyr   Zmax_infoN)r   r{   rÀ   )ry   Úch_usedÚhas_megÚhas_sssr4   r§  r5   Ú
_check_sss$  s    ÿrŒ  c              
      sÖ  |d krt ƒ n|}td|ƒ}tˆ ddd�}tˆ |ƒ‰ tˆ ƒ\}}}|r`d|ksVd|krptdƒ‚nd|krptd	ƒ‚tˆ |d
�}|r�tt|Ž ƒd }dd„ t	t||ƒƒD ƒ}t
|ƒ}	dd„ |D ƒ}
|rÒ|
tˆ dd
�7 }
g }|D ]î}ˆ  ¡ }| ¡ � |d  |d 7  < W 5 Q R X i }|
D ]¦\}}d|k�rVd|k�rVd|k�rV|d |d  |d<  �q¾| |¡d k�rž‡ fdd„|D ƒ}t||ƒ}t|||d�| }|||< n| |¡d k	�r|| ||< �q| |¡ qÚ|	|||fS )NZscalings_cov_rankFr©  r  r*   r)   zfWhen using SSS, pass "meg" to set the rank (separate rank values for "mag" or "grad" are meaningless).ZmegzVWhen not using SSS, pass separate rank values for "mag" and "grad" (do not use "meg").)Zmeg_combinedr   c                 S   s   g | ]\}}|‘qS r4   r4   )rs   rƒ   ry  r4   r4   r5   r„   D  s     z$_triage_rank_sss.<locals>.<listcomp>c                 S   s   g | ]}|‘qS r4   r4   )rs   rl  r4   r4   r5   r„   I  s     Trv   c                    s   g | ]}ˆ d  | ‘qS rå  r4   r¥  r§  r4   r5   r„   c  s     )rö  ry   )rh   r   r   r   rŒ  r�   r   r‰   r¿   rô   r{   rÿ  r{  rÀ   r   r   rö   )ry   Zcovsr‚  rö  rÌ   r‰  rŠ  r‹  Ú
picks_listZ	n_ch_usedZpicks_list2Z	rank_listrƒ  Z	info_projZ	this_rankrÂ  Z
this_picksr³  Zthis_CZthis_estimated_rankr4   r§  r5   r„  .  sZ    



ÿ
  ÿÿ
r„  c                 C   s>   ddl m} | dkrdS || ddd�} t|ƒd r:tdƒ | S )z;Check the noise_cov for whitening and issue an SSS warning.r   )Ú_ensure_covNr†  F)r‘   r   z˜Data have been processed with SSS, which changes the relative scaling of magnetometers and gradiometers when viewing data whitened by a noise covariance)rƒ  rŽ  rŒ  r'   )r†  ry   rŽ  r4   r4   r5   Ú
_check_covo  s    r�  rš   c                 C   s²   | dkr®d  |d|… ¡} t ||¡}|dkr2d}t|ƒdkrF|d7 }|dkrtt|tƒrt| ¡ }d |t|ƒ|¡} n:t|ƒ|kr®|dkr®t 	d	 |¡¡ | d
 |t|ƒ|¡7 } | S )z/Prepare a title string for multiple electrodes.Nú, ZsensorrO   r  Tz{} of {} {}r’  z+More than {} channels, truncating title ...z, ...
({} of {} {}))
ÚjoinÚ_channel_type_prettyprintrÀ   r{   r�   rl   Ú
capitalizer?   r    ry   )rø   Úcombiner³  Z	max_chansrx   rÂ  r4   r4   r5   Ú_set_title_multiple_electrodes|  s0      ÿÿ  ÿr•  c                 C   sL   t | tƒstdt| ƒf ƒ‚| dkr&n| dkr8d| }ntd|  ƒ‚| |fS )Nztime_unit must be str, got %sr  Úmsg     @�@z%time_unit must be 's' or 'ms', got %r)r�   rl   r�   r�   r�   )ru  rŽ  r4   r4   r5   Ú_check_time_unit’  s    

r—  r  Úbothrç   ÚGreysÚlinearc           !   	   C   sê  ddl m} ddlm} |	dkr,|dk	r,d}	|	dk}|	dk}|dkrH|}|dkr\|||d�}|dkrv|dk	rrd	}nd
}|dkr�|dk	rŒd	}nd
}|dkr¸|r¨tdƒ d
}|r¸tdƒ d
}|rð|j|jkrÜtd|j|jf ƒ‚|rð|dkrðtdƒ |dk�r
t |jd ¡}|dk�r*|d dk�s*tdƒ‚t	|ƒdk �sF|d dk�rLd}n"|dk�rn|dd… |dd…  }|dk�r¢|d dk�ržt 
||d ¡�ržd}nd}|dk�rüt|ƒ\}t |d |d  g||d |d  gg¡}t |dd… |dd…  ¡}t ||¡\}}|dk	�rT| j||||||
d� | j||tj | |¡||dd�}n| j|||||d�}|dk�r~|ddg }|dk�r¤|  d¡ |  ¡  | ¡ ¡ | j | ¡ ¡ | j | ¡ ¡ |t t dt	|ƒd d¡ ¡  d¡¡ }|  |¡ �npt	|ƒdk�rt  t !|¡¡d nd}t	|ƒdk�rDt  t !|¡¡d nd}|d | |d | |d | |d | g}t"dd|dd�}|�rÊ| j#|f|
||d œ|—Ž | j#tj | |¡f||dœ|—Ž}n0| j#|f||dœ|—Ž | j#|f||dœ|—Ž}|�rBt |¡j$dk�rBt %|t &d!¡¡}| j'|d"g|d#gd
d
dgd$� |d |d g}|dk�rl|d |d% g}|  (|d |d ¡ |  )|¡ |�s–|�rÞ|dk	�rÞ| *¡ �r°d&}n,dt +| ,¡ ¡t +|j$¡  } d'| d( f }nd)}||fS )*z6Plot a potentially masked (evoked, TFR, ...) 2D image.r   )Úticker)Ú	NormalizeNr˜  >   Úmaskr˜  >   Úcontourr˜  )r8   r9   TFz(`mask` is None, not masking the plot ...z2`mask` is None, not adding contour to the plot ...z?The mask must have the same shape as the data, i.e., %s, not %sÚlogz/Cannot draw contours with linear yscale yet ...zˆUsing log scale for frequency axis requires all your frequencies to be positive (you cannot include the DC component (0 Hz) in the TFR).r   rš  rO   rœ   râ   )r  rB   r£   )r  rB   r>  rî   rù  rå   r�   ZnearestrZ   )ÚinterpolationÚoriginrQ  rˆ  )r£   r  rB   )r”   r”   rl  ç      è?)r›   rQ  Z
linewidthsZcorner_maskZantialiasedZlevelsr™   z, all points masked)z, %0.3g%% of points masked)éd   rØ   )-rI   r›  Zmatplotlib.colorsrœ  r'   rX  r�   r:   r±   r{   ZallcloseÚcenters_to_edgesr¯   rñ   ZmeshgridZ
pcolormeshÚmaZmasked_whereZ
set_yscaleZ	get_yaxisÚset_major_formatterÚScalarFormatterrí  Zset_minor_formatterZNullFormatterZset_minor_locatorZNullLocatorrÞ   r˜  r  rj  rp  Úmedianr®   rh   r[  rù   Zkronr½  rž  rk  rl  rx   Zfloat64Úsum)!rE  rA   rŽ  r�  Zyvalsr  r8   r9   rn  Z
mask_styleZ
mask_alphaZ	mask_cmapZyscaleZcnormr›  rœ  Z	draw_maskZdraw_contourÚratioZ	time_limsZ	log_yvalsZ	yval_limsZ	time_meshZ	yval_meshr\  Z	tick_valsÚdtr+  rQ  Zim_argsZbig_maskZt_endZfractionr4   r4   r5   Ú_plot_masked_imagež  sô    
ÿÿ


 

ÿ
 ÿ  þÿ



 
 ÿÿ&&
 
ÿÿÿÿÿ  þ


r¬  c                 C   sp   | dkrt tjdd�} nTt| tƒrldd„ dD ƒ}dd„ |d	< z||  } W n" tk
rj   td
 | ¡ƒ‚Y nX | S )aŠ  Convert None or string values of ``combine`` into callables.

    Params
    ------
    %(combine)s
        If callable, the callable must accept one positional input (data of
        shape ``(n_epochs, n_channels, n_times)`` or ``(n_evokeds, n_channels,
        n_times)``) and return an :class:`array <numpy.ndarray>` of shape
        ``(n_epochs, n_times)`` or ``(n_evokeds, n_times)``.
    NrO   rŒ  c                 S   s    i | ]}|t tt|ƒd d�“qS )rO   rŒ  )r   rÔ  r:   )rs   rÐ   r4   r4   r5   rÓ   7  s   ÿ z*_make_combine_callable.<locals>.<dictcomp>)r¾  r¨  r�  c                 S   s   t  | d jdd�¡S )Nr   rO   rŒ  )r:   rñ   r¾  )rA   r4   r4   r5   rÖ   9  r×   z(_make_combine_callable.<locals>.<lambda>r’  zW"combine" must be None, a callable, or one of "mean", "median", "std", or "gfp"; got {})r   r:   Zsqueezer�   rl   rÜ   r�   r?   )r”  Zcombine_dictr4   r4   r5   Ú_make_combine_callable(  s    
ÿþr­  Úchannelc                    sJ  t d|ddgƒ t |  d¡dk¡d }t|ƒdkr°|r>d}nd}|dkrdd ‡ fd	d
„|D ƒ¡}	nd dd
„ |D ƒ¡}	|› d|› t|ƒ› d|	› d�}
|dkr¦|
d7 }
t|
tƒ |dkrÄ|rÀdnd}|dkrìtj	| | d� | |9 } d| }n&| || 9 } d|k�r
d| }d| }|�rFtj
t | t t¡j¡| d� | d9 } |d7 }|S )aô  Convert PSDs to dB (if necessary) and appropriate units.

    The following table summarizes the relationship between the value of
    parameters ``dB`` and ``estimate``, and the type of plot and corresponding
    units.

    | dB    | estimate    | plot | units             |
    |-------+-------------+------+-------------------|
    | True  | 'power'     | PSD  | amp**2/Hz (dB)    |
    | True  | 'amplitude' | ASD  | amp/sqrt(Hz) (dB) |
    | True  | 'auto'      | PSD  | amp**2/Hz (dB)    |
    | False | 'power'     | PSD  | amp**2/Hz         |
    | False | 'amplitude' | ASD  | amp/sqrt(Hz)      |
    | False | 'auto'      | ASD  | amp/sqrt(Hz)      |

    where amp are the units corresponding to the variable, as specified by
    ``unit``.
    Ú	first_dimr®  ÚepochrO   r   ZInfiniteZZeror�  c                 3   s   | ]}ˆ | V  qd S rÔ   r4   ©rs   r  rå  r4   r5   ru   b  s     z _convert_psds.<locals>.<genexpr>c                 s   s   | ]}t |ƒV  qd S rÔ   )rl   r±  r4   r4   r5   ru   d  s     z value in PSD for r#  r¡  z
These channels might be dead.râ   ÚpowerZ	amplitude)rm  z$\mathrm{%s/\sqrt{Hz}}$ú/z(%s)u   $\mathrm{%sÂ²/Hz}$r”   z$\ \mathrm{(dB)}$)r   r:   rŽ   r=   r{   r‘  r"   r'   r@   rñ   rh  ÚmaximumZfinfor—   Ztiny)ZpsdsÚdBÚestimateZscalingrs  r³  r¯  rŽ   Z	bad_valuer©  ÚmsgÚylabelr4   rå  r5   Ú_convert_psdsC  s8    


r¹  c           ,         s®  ddl m} ddlm} tdddgddd	gƒD ]<\}}ˆ j| d k	r.|D ] }|jˆ j| d
|dddd� qHq.|d kr€|r|dnd}t|ƒ}tƒ }t	t||||||ƒƒD ]à\}\}}}}}} t
||||| ‡ fdd„|D ƒƒ}!| |!¡ ~!|r¤tj|dd�}"|dk�r tj|dd�}#|"|# |"|# f}$n,|dk�rHtj|dd�tj|dd�f}$nd }$|j||"|
|dd� |$d k	r¤|j||$d |$d |
|d� q¤|�sÒt |¡}t |¡}t ˆ j|d�¡}%t‡ fdd„|D ƒˆ jd |%ƒ}&|& ¡ �* ‡ fdd„|D ƒ|&d< ˆ jd |&d< W 5 Q R X tƒ }'tD ]}(|(|%k�r|' |(¡ �qt|'ƒt|ƒk�sFt‚d})dd „ t|'|ƒD ƒ} d!d „ t|'|ƒD ƒ}*t t|ƒ¡}|�sŠ|
}|||&|||||)| d d d"|%d|d |d# fd |g |*|'d$d$|d d%|d d&� t	t||ƒƒD ]¶\}\}}+|jd$d'd(� |d)k�rP|jd)d*� |j|d dk�r*|d n|d |d# gd+� | ¡  |ƒ ¡ n|j|d |d# fd+� |	�rà|j|| || d,� |+�rà|  d-¡ �qà|	�rª|j!|d.� |S )/Nr   )r§  rO   )Ú_plot_linesrx  ZhighpassZ	line_freqrk  z-.rl  rç   r   )re  rZ  r£   r¸  rÜ  rŸ   r¢  c                    s   g | ]}ˆ j | ‘qS r4   rå  )rs   Úpirú  r4   r5   r„   •  s     z_plot_psd.<locals>.<listcomp>rŒ  r�  ró   r�   )re  r£   r¸  )Úy2Z	facecolorr£   rË   c                    s   g | ]}ˆ j | ‘qS r4   rå  rr   rú  r4   r5   r„   ±  s     rø  c                    s   g | ]}ˆ j d  | ‘qS r£  r§  rr   rú  r4   r5   r„   ´  s     r¤  r¢  rÛ  c                 S   s   i | ]\}}||“qS r4   r4   )rs   ÚtZylr4   r4   r5   rÓ   ¼  s      z_plot_psd.<locals>.<dictcomp>c                 S   s   i | ]\}}||“qS r4   r4   )rs   r©   r½  r4   r4   r5   rÓ   ½  s      Frœ   Tr–  )Úunitsrö  rt  r’  ÚtypesrÜ  rm  rn  rŽ  Z
bad_ch_idxÚtitlesÚch_types_usedZ
selectableÚpsdÚ
line_alphar‡  ru  rÅ  Ú	highlightú:)rZ  rŸ  )Úxscale)rm  )r¸  rø   zFrequency (Hz))Zaxs)"r/  r§  r‘  rº  r¿   ry   Zaxvliner—   r‰   r¾   r¹  rö   r:   r¾  r�  r=   r<   ZplotZfill_betweenr¯   r°   rû  r   r{  r   r{   r~  r±   ÚgridrÝ   Z	get_xaxisr¦  rq  Zalign_ylabels),r™  rL   ZfreqsZpsd_listr�  Ztitles_listZ
units_listZscalings_listZax_listZ
make_labelre  Z	area_modeZ
area_alpharµ  r¶  ZaverageZspatial_colorsrÆ  rÃ  rÅ  Zxlabels_listr§  rº  rÐ   ZlsrE  Zylabelsr  rÂ  rÌ   rø   rö  r¾  r¸  Zpsd_meanZpsd_stdZ
hyp_limitsr¿  ry   rÁ  rÆ  rs  rÀ  Zxlabelr4   rú  r5   Ú	_plot_psd  sÒ    
ÿ  ÿ
    þÿ


ÿÿ ÿ

 ÿ

              ú
.rÈ  c                 C   s:   t  ||¡rd}nt  t  | |k| |k¡¡}t  | | ¡S )z9Remove ticks that are more extreme than the given limits.r   )r:   ÚiscloserŽ   Úlogical_andZ
atleast_1d)ZticksÚ_minÚ_maxZkeep_idxr4   r4   r5   ro  Û  s    ro  c                 C   s   | j jd k	r| j j |¡ d S rÔ   )rf   ÚmanagerÚset_window_title)rL   rø   r4   r4   r5   r  ä  s    r  é<   ú...c           	      C   sÎ   ddl m} t| ƒ|krÊ|  |¡}tttt|ƒd d ddƒtt|ƒd t|ƒd ƒƒƒ}t |¡ 	¡ }|D ]X}|||< t |¡|k 
¡ d }| |d|d … ||d d…  ¡}t|ƒ|k rl qÆql|S | S )zCTruncate a path from the middle by omitting complete path elements.r   )Úsepr   rO   rœ   N)Úos.pathrÑ  r{   r  r‰   r¿   ró   r:   r°   Úflattenrï  r‘  )	ZfpathÚmax_lenÚreplacementrÑ  ZpathlistZixs_to_truncZixZtruncsÚnewpathr4   r4   r5   Ú_shorten_path_from_middleé  s    
ÿ&r×  c               
   G   s¾   t ƒ }t| ƒD ]ª\}}tj|td�}td|› d�|jdƒ t|ƒdkrVt |¡d }n$|d dkrtt	|d ƒd gndg}| 
t |d |d  g|d	d
… | |d
 |d
  gg¡¡ q|S )a  Convert center points to edges.

    Parameters
    ----------
    *arrays : list of ndarray
        Each input array should be 1D monotonically increasing,
        and will be cast to float.

    Returns
    -------
    arrays : list of ndarray
        Given each input of shape (N,), the output will have shape (N+1,).

    Examples
    --------
    >>> x = [0., 0.1, 0.2, 0.3]
    >>> y = [20, 30, 40]
    >>> centers_to_edges(x, y)  # doctest: +SKIP
    [array([-0.05, 0.05, 0.15, 0.25, 0.35]), array([15., 25., 35., 45.])]
    r˜   zarrays[z].ndim©rO   rO   rù  r   gü©ñÒMbP?Nrœ   )r‰   r¾   r:   r¬   r—   r   rŒ   r{   r®   r;   rö   r¯   )Zarraysrm  ZaiZarrZarr_diffr4   r4   r5   r¤  ý  s    $ý
r¤  c                  K   s.   ddl m} ddlm} |f | Ž}||ƒ |S )Nr   )ÚFigureCanvasAgg)ÚFigure)Zmatplotlib.backends.backend_aggrÙ  Zmatplotlib.figurerÚ  )r3   rÙ  rÚ  rL   r4   r4   r5   Ú_figure_agg!	  s
    
rÛ  r£  c                 C   sR   t  | jdd… ddd… ¡| }t||d�}|jddddgdd�}| | ¡ |S )	z<Convert to MPL figure, adapted from matplotlib.image.imsave.Nr   rœ   )rK  ré   r   rO   F)Zframe_on)r:   r°   rX  rÛ  r  r[  )ÚimgrK  ré   rL   rE  r4   r4   r5   Ú_ndarray_to_fig)	  s
    "
rÝ  c                 C   s    ddl m} | |¡ | ¡ dS )zSave an image to disk.r   )ÚImageN)ZPILrÞ  Z	fromarrayÚsave)ÚfnamerÜ  rÞ  r4   r4   r5   Ú_save_ndarray_img2	  s    rá  Úblackr™   c                 C   s†  t |dƒ}t |ƒ}td|dƒ td|dƒ |dkr6dnd}t|d|d	�}t |¡d
 }tjtjg}t || dd„ | D ƒƒ|d|  dd„ | D ƒƒg¡}tj|d |d |ftjd�}||dd…dd…dd…f< t 	ddg¡}	t 	d|kd|kg¡ 
t¡}
| D ]‚}|jdd… }|	 ¡ }||�r4|| d d|
  nd7 }|||d |d |d  …|d |d |d  …dd…f< |	||
 7 }	qþ|S )aÍ  Concatenate a list of images.

    Parameters
    ----------
    images : list of ndarray
        The list of images to concatenate.
    axis : 0 or 1
        The images are concatenated horizontally if 0 and vertically otherwise.
        The default orientation is horizontal.
    bgcolor : str | list
        The color of the background. The name of the color is accepted
        (e.g 'red') or a list of RGB values between 0 and 1. Defaults to
        'black'.
    centered : bool
        If True, the images are centered. Defaults to True.
    n_channels : int
        Number of color channels. Can be 3 or 4. The default value is 3.

    Returns
    -------
    img : ndarray
        The concatenated image.
    Ú
n_channelsr]  )r   rO   )r™   rž   rž   TFÚbgcolor)r‘   r£   r¦   c                 S   s   g | ]}|j d  ‘qS r´  ©rX  ©rs   Úimager4   r4   r5   r„   Z	  s     z&concatenate_images.<locals>.<listcomp>rO   c                 S   s   g | ]}|j d  ‘qS rØ  rå  ræ  r4   r4   r5   r„   [	  s     r   r˜   Nrœ   r   )r$   r   r&   r:   r¬   r©  r<   r¿  Zuint8r°   rj  rî   rX  rÿ  )Zimagesr]  rä  Zcenteredrã  r£   ÚfuncsZ	ret_shapeÚretZptrÚsecrç  rX  Údecr4   r4   r5   Úconcatenate_images8	  s.    
þ":rì  ú.pngc                 C   s   t  ¡ }| d¡}d| |  S )Nz_%Y-%m-%d_%H-%M-%SZMNE)r   ÚnowÚstrftime)Úextrî  Z	dt_stringr4   r4   r5   Ú_generate_default_filenamej	  s    
rñ  c                 C   s,   ddl m} dt|ƒkrdn| }|d |iS )Nr   )ÚSpanSelectorÚpropsrÛ  )r4  rò  r	   )rƒ  Úvalrò  Úprer4   r4   r5   r>  p	  s    r>  c                 C   sN   t | ttd fdƒ | d krJtddƒ ¡ } td| ddd� tdddd�|  } | S )	NÚ
precomputeZMNE_BROWSER_PRECOMPUTErâ   )rS   rR   râ   zwhen precompute=None is usedr‡   TF)r%   rW   rl   r   rZ   r   rh   )rö  r4   r4   r5   Ú_handle_precomputex	  s     þr÷  c                 C   s    |   ¡ |  ¡ |  ¡   }}}dd„ }||ƒ\}}||ƒ\}}||ƒ\}	}
dt|||	gƒ }|  || || g¡ |  || || g¡ |  |
| |
| g¡ dS )a~  Make axes of 3D plot have equal scale on all dimensions.

    This way spheres appear as actual spheres, cubes as cubes, etc..
    This is one possible solution to Matplotlib's ``ax.set_aspect('equal')``
    and ``ax.axis('equal')`` not working for 3D.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        A matplotlib 3d axis to use.

    Notes
    -----
    modified from:
    https://stackoverflow.com/q/13685386

    Should no longer be necessary for matplotlib >= 3.3.0:
    https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.3.0.html#axes3d-no-longer-distorts-the-3d-plot-to-match-the-2d-aspect-ratio
    c                 S   s   | d | d  t  | ¡fS )NrO   r   )r:   r¾  )Zlimr4   r4   r5   Ú	get_range™	  s    z%_set_3d_axes_equal.<locals>.get_ranger�   N)Z
get_xlim3dZ
get_ylim3dZ
get_zlim3dr<   Z
set_xlim3dZ
set_ylim3dZ
set_zlim3d)rE  Zx_limZy_limZz_limrø  Zx_rangeZx_meanZy_rangeZy_meanZz_rangeZz_meanZplot_radiusr4   r4   r5   Ú_set_3d_axes_equalƒ	  s    rù  c                 C   sL   t | tttfdƒ t| tƒr"| g} t| ƒD ]\}}t |td|› d�ƒ q*| S )Nrv   zprojs[ú])r%   r‰   rŠ   r   r�   r¾   )rv   r»  rt   r4   r4   r5   Ú_check_type_projs¨	  s    
rû  )F)TN)TTN)r]   NNN)Nr~   )F)N)NN)râ   FFrã   FF)T)rE  rO   rx  )N)NF)rœ  NNFNTNFTNNr   N)Nr   )Fr”   )rO   F)N)F)r4   )rŸ   r|  )FNTTFTr  )TTrO   )NN)rš   FN)NNr  NNNr˜  rç   r™  rš  N)Nr®  )rÏ  rÐ  )r£  )r   râ  Tr™   )rí  )‚rw  Úcollectionsr   Ú
contextlibr   r   r)  Ú	functoolsr   rï   rX   r0   r,  r.   ri   r0  r   Únumpyr:   Údefaultsr   Úfixesr	   Úior
   r   Zio.constantsr   Zio.meas_infor   Zio.pickr   r   r   r   r   r   r   r   r   r   r   Zio.projr   r   r‚  r   rz  r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   Z
transformsr(   r’  r6   rC   rN   r\   rk   r}   r’   r¸   rº   rÆ   rÎ   rá   rÿ   r  r  r   Úinfr2  r  rI  rM  r  ÚobjectrP  r…  rŠ  r”  r›  rË  rÓ  rÕ  rÀ  r  r  r  r  r&  rî  rP  rW  r]  r^  rv  r}  rˆ  rŒ  r„  r�  r•  r—  r¬  r­  r¹  rÈ  ro  r  r×  r¤  rÛ  rÝ  rá  rì  rñ  r>  r÷  rù  rû  r4   r4   r4   r5   Ú<module>   s6  48   û

(

!
6

Y



      ÿ
2
3	  ÿ0_

,
                   ý /  þ
]
f

"q	{
$
  ÿ
B           þ
G  ÿ
,

A    ÿ
                ý
 
  ÿ
<\	
$
	  ÿ
2
%