U
    Y»{j9  ã                   @   sx   d dl mZ d dlZd dlmZmZ d dlmZ d dlm	Z	 e 
d¡Zdd„ Zd	ejd
 dfdd„ZG dd„ deƒZdS )é    )Úabsolute_importN)Ú
exceptionsÚoptional_imports)Úutils)Ú
graph_objsÚnumpyc                 C   s¤   t dkrtdƒ‚tt| ƒd ƒD ]6}| |d  | |  | d | d   dkr t d¡‚q tt|ƒd ƒD ]6}||d  ||  |d |d   dkrht d¡‚qhdS )	as  
    Streamline-specific validations

    Specifically, this checks that x and y are both evenly spaced,
    and that the package numpy is available.

    See FigureFactory.create_streamline() for params

    :raises: (ImportError) If numpy is not available.
    :raises: (PlotlyError) If x is not evenly spaced.
    :raises: (PlotlyError) If y is not evenly spaced.
    Fz.FigureFactory.create_streamline requires numpyé   r   g-Cëâ6?z.x must be a 1 dimensional, evenly spaced arrayz.y must be a 1 dimensional, evenly spaced arrayN)ÚnpÚImportErrorÚrangeÚlenr   ZPlotlyError)ÚxÚyÚindex© r   ú`/var/www/html/bwave/python/venv/lib/python3.8/site-packages/plotly/figure_factory/_streamline.pyÚvalidate_streamline   s    (ÿ(ÿr   r   é	   g
×£p=
·?c                 K   s¨   t  | |¡ t  ||¡ t| |ƒ t j||d� t| ||||||ƒ ¡ \}}	t| ||||||ƒ ¡ \}
}tjf ||
 |	| ddœ|—Ž}|g}tj	dd�}tj
||d�S )aa	  
    Returns data for a streamline plot.

    :param (list|ndarray) x: 1 dimensional, evenly spaced list or array
    :param (list|ndarray) y: 1 dimensional, evenly spaced list or array
    :param (ndarray) u: 2 dimensional array
    :param (ndarray) v: 2 dimensional array
    :param (float|int) density: controls the density of streamlines in
        plot. This is multiplied by 30 to scale similiarly to other
        available streamline functions such as matplotlib.
        Default = 1
    :param (angle in radians) angle: angle of arrowhead. Default = pi/9
    :param (float in [0,1]) arrow_scale: value to scale length of arrowhead
        Default = .09
    :param kwargs: kwargs passed through plotly.graph_objs.Scatter
        for more information on valid kwargs call
        help(plotly.graph_objs.Scatter)

    :rtype (dict): returns a representation of streamline figure.

    Example 1: Plot simple streamline and increase arrow size

    >>> from plotly.figure_factory import create_streamline
    >>> import plotly.graph_objects as go
    >>> import numpy as np
    >>> import math

    >>> # Add data
    >>> x = np.linspace(-3, 3, 100)
    >>> y = np.linspace(-3, 3, 100)
    >>> Y, X = np.meshgrid(x, y)
    >>> u = -1 - X**2 + Y
    >>> v = 1 + X - Y**2
    >>> u = u.T  # Transpose
    >>> v = v.T  # Transpose

    >>> # Create streamline
    >>> fig = create_streamline(x, y, u, v, arrow_scale=.1)
    >>> fig.show()

    Example 2: from nbviewer.ipython.org/github/barbagroup/AeroPython

    >>> from plotly.figure_factory import create_streamline
    >>> import numpy as np
    >>> import math

    >>> # Add data
    >>> N = 50
    >>> x_start, x_end = -2.0, 2.0
    >>> y_start, y_end = -1.0, 1.0
    >>> x = np.linspace(x_start, x_end, N)
    >>> y = np.linspace(y_start, y_end, N)
    >>> X, Y = np.meshgrid(x, y)
    >>> ss = 5.0
    >>> x_s, y_s = -1.0, 0.0

    >>> # Compute the velocity field on the mesh grid
    >>> u_s = ss/(2*np.pi) * (X-x_s)/((X-x_s)**2 + (Y-y_s)**2)
    >>> v_s = ss/(2*np.pi) * (Y-y_s)/((X-x_s)**2 + (Y-y_s)**2)

    >>> # Create streamline
    >>> fig = create_streamline(x, y, u_s, v_s, density=2, name='streamline')

    >>> # Add source point
    >>> point = go.Scatter(x=[x_s], y=[y_s], mode='markers',
    ...                    marker_size=14, name='source point')

    >>> fig.add_trace(point) # doctest: +SKIP
    >>> fig.show()
    )ÚdensityÚarrow_scaleÚlines)r   r   ÚmodeZclosest)Z	hovermode)ÚdataÚlayout)r   Zvalidate_equal_lengthr   Zvalidate_positive_scalarsÚ_StreamlineÚsum_streamlinesÚget_streamline_arrowsr   ZScatterZLayoutZFigure)r   r   ÚuÚvr   Úangler   ÚkwargsÚstreamline_xÚstreamline_yZarrow_xZarrow_yZ
streamliner   r   r   r   r   Úcreate_streamline'   s@    I
      ÿ      ÿ  ÿÿ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 )r   zB
    Refer to FigureFactory.create_streamline() for docstring
    c                 K   s€  t  |¡| _t  |¡| _t  |¡| _t  |¡| _|| _|| _td| ƒ| _	| jd | jd  | _
| jd | jd  | _| j| _| j| _t  | j	| j	f¡| _t| jƒt| j	d ƒ | _t| jƒt| j	d ƒ | _g | _| j| jd | jd   | _| j| jd | jd   | _t  | jd | jd  ¡| _|  jt| jƒ9  _|  jt| jƒ9  _g | _g | _|  ¡  |  ¡ \}	}
|  ¡ \}}d S )Né   r   r   éÿÿÿÿé   )r	   Úarrayr   r   r   r   r   r   Úintr   Údelta_xÚdelta_yÚval_xÚval_yZzerosÚblankr   ÚfloatÚ	spacing_xÚ	spacing_yÚtrajectoriesÚsqrtÚspeedÚst_xÚst_yÚget_streamlinesr   r   )Úselfr   r   r   r   r   r   r   r    r!   r"   Úarrows_xÚarrows_yr   r   r   Ú__init__‹   s2    z_Streamline.__init__c                 C   s$   t || j d ƒt || j d ƒfS )zQ
        Set up positions for trajectories to be used with rk4 function.
        ç      à?)r(   r/   r0   )r7   ÚxiÚyir   r   r   Ú	blank_pos¬   s    z_Streamline.blank_posc                 C   sÚ   t |tjƒr&| t¡| _| t¡| _nt|ƒ| _t|ƒ| _|| j| jf }|| j| jd f }|| jd | jf }|| jd | jd f }|| j }|| j }	|d|  ||  }
|d|  ||  }|
d|	  ||	  S )zK
        Set up for RK4 function, based on Bokeh's streamline code
        r   )	Ú
isinstancer	   ZndarrayZastyper(   r   r   r+   r,   )r7   Úar<   r=   Za00Za01Za10Za11ZxtZytZa0Za1r   r   r   Úvalue_at²   s    



z_Streamline.value_atc                    s  ‡fdd„}‡fdd„}‡fdd„‰ g ‰g ‰‡ ‡‡‡fdd„}||||ƒ\}}}||||ƒ\}	}
}||	 }|
d	d	d
… |dd	…  }|d	d	d
… |dd	…  }t |ƒdk r®d	S |dkrÜˆ ||¡\}}dˆj||f< ||fS tˆˆƒD ]\}}dˆj||f< qæd	S d	S )zç
        RK4 forward and back trajectories from the initial conditions.

        Adapted from Bokeh's streamline -uses Runge-Kutta method to fill
        x and y trajectories then checks length of traj (s in units of axes)
        c                    sD   dˆ   ˆ j| |¡ }ˆ   ˆ j| |¡}ˆ   ˆ j| |¡}|| || fS ©Ng      ð?©rA   r3   r   r   ©r<   r=   Zdt_dsZuiÚvi©r7   r   r   ÚfÎ   s    z$_Streamline.rk4_integrate.<locals>.fc                    sH   dˆ   ˆ j| |¡ }ˆ   ˆ j| |¡}ˆ   ˆ j| |¡}| | | | fS rB   rC   rD   rF   r   r   ÚgÔ   s    z$_Streamline.rk4_integrate.<locals>.gc                    sD   d|   kot ˆ jƒd k n  oBd|  ko>t ˆ jƒd k S   S )Nr   r   )r   r   r   )r<   r=   rF   r   r   Ú<lambda>Ú   ó    z+_Streamline.rk4_integrate.<locals>.<lambda>c                    sÀ  d}d}| }|}ˆ  ||¡\}}g }	g }
ˆ ||ƒ�r¶|	 |¡ |
 |¡ z||||ƒ\}}||d| |  |d| |  ƒ\}}||d| |  |d| |  ƒ\}}||||  |||  ƒ\}}W n tk
rÞ   Y �q¶Y nX |||d|  d|  |  d 7 }|||d|  d|  |  d 7 }ˆ ||ƒ�s8�q¶||7 }ˆ  ||¡\}}||k�sd||k�r¨ˆj||f dk�r¶dˆj||f< ˆ |¡ ˆ |¡ |}|}n�q¶|dkr(�q¶q(||	|
fS )Ng{®Gáz„?r   r;   r&   g      @r   )r>   ÚappendÚ
IndexErrorr-   )Úx0Úy0rG   ZdsÚstotalr<   r=   ÚxbÚybÚxf_trajÚyf_trajZk1xZk1yZk2xZk2yZk3xZk3yZk4xZk4yZnew_xbZnew_yb©Úcheckr7   Z
xb_changesZ
yb_changesr   r   Úrk4Þ   sD    

&&"$$

z&_Streamline.rk4_integrate.<locals>.rk4Nr%   r   gš™™™™™É?r   )r   r>   r-   Úzip)r7   rM   rN   rG   rH   rV   ZsfrR   rS   ÚsbZxb_trajZyb_trajrO   Zx_trajZy_trajZinitxbZinitybrP   rQ   r   rT   r   Úrk4_integrateÆ   s(    %z_Streamline.rk4_integratec                 C   sj   |dk s$|| j ks$|dk s$|| j kr(dS | j||f dkrf|  || j || j ¡}|dk	rf| j |¡ dS )z÷
        Integrate trajectories

        :param (int) xb: results of passing xi through self.blank_pos
        :param (int) xy: results of passing yi through self.blank_pos

        Calculate each trajectory based on rk4 integrate method.
        r   N)r   r-   rY   r/   r0   r1   rK   )r7   rP   rQ   Útr   r   r   Útraj  s    
$z_Streamline.trajc                    s$  t ˆ jd ƒD ]p}t ˆ jd|  ƒD ]X}ˆ  || |¡ ˆ  || ˆ jd | ¡ ˆ  ||| ¡ ˆ  ˆ jd | || ¡ q$q‡ fdd„ˆ jD ƒˆ _‡ fdd„ˆ jD ƒˆ _t tˆ jƒƒD ]*}ˆ j|  ¡ ˆ j|< ˆ j|  t	j
¡ qºt tˆ jƒƒD ]*}ˆ j|  ¡ ˆ j|< ˆ j|  t	j
¡ qôdS )z=
        Get streamlines by building trajectory set.
        r&   r   c                    s*   g | ]"}t  |d  ¡ˆ j ˆ jd   ‘qS )r   )r	   r'   r)   r   ©Ú.0rZ   rF   r   r   Ú
<listcomp>0  s    z/_Streamline.get_streamlines.<locals>.<listcomp>c                    s*   g | ]"}t  |d  ¡ˆ j ˆ jd  ‘qS )r   r   )r	   r'   r*   r   r\   rF   r   r   r^   3  s    N)r   r   r[   r1   r4   r5   r   ÚtolistrK   r	   Únan)r7   Úindentr<   r   r   rF   r   r6   %  s$    
ÿ
ÿz_Streamline.get_streamlinesc                 C   sü  t  t| jƒ¡}t  t| jƒ¡}t  t| jƒ¡}t  t| jƒ¡}tt| jƒƒD ]œ}| j| tt| j| ƒd ƒ ||< | j| tt| j| ƒd ƒd  ||< | j| tt| j| ƒd ƒ ||< | j| tt| j| ƒd ƒd  ||< qN|| }|| }t  ¡ }t jddd� t  	|| ¡}	t jf |Ž |	| j
 }
|	| j
 }t  |
¡| j }t  |
¡| j }t  |¡| j }t  |¡| j }t  t|ƒ¡}t  t|ƒ¡}t  t|ƒ¡}t  t|ƒ¡}tt|ƒƒD ]¶}|| dk�r(|| ||  ||< || ||  ||< || ||  ||< || ||  ||< nP|| ||  ||< || ||  ||< || ||  ||< || ||  ||< �qÄt  t|ƒ¡}t j|dd…< t  ||||g¡}t  |¡}| d¡}| ¡ }t  ||||g¡}t  |¡}| d¡}| ¡ }||fS )a_  
        Makes an arrow for each streamline.

        Gets angle of streamline at 1/3 mark and creates arrow coordinates
        based off of user defined angle and arrow_scale.

        :param (array) st_x: x-values for all streamlines
        :param (array) st_y: y-values for all streamlines
        :param (angle in radians) angle: angle of arrowhead. Default = pi/9
        :param (float in [0,1]) arrow_scale: value to scale length of arrowhead
            Default = .09
        :rtype (list, list) arrows_x: x-values to create arrowhead and
            arrows_y: y-values to create arrowhead
        é   r   Úignore)ÚdivideÚinvalidr   NÚF)r	   Úemptyr   r4   r5   r   r(   ZgeterrZseterrZarctanr   Úcosr   Úsinr`   Úmatrixr'   Úflattenr_   )r7   Zarrow_end_xZarrow_end_yZarrow_start_xZarrow_start_yr   Zdif_xZdif_yZorig_errZstreamline_angZang1Zang2Zseg1_xZseg1_yZseg2_xZseg2_yZpoint1_xZpoint1_yZpoint2_xZpoint2_yÚspacer8   r9   r   r   r   r   ?  sd    $ÿ$ÿ






z!_Streamline.get_streamline_arrowsc                 C   s    t | jg ƒ}t | jg ƒ}||fS )a  
        Makes all streamlines readable as a single trace.

        :rtype (list, list): streamline_x: all x values for each streamline
            combined into single list and streamline_y: all y values for each
            streamline combined into single list
        )Úsumr4   r5   )r7   r!   r"   r   r   r   r   Ž  s    z_Streamline.sum_streamlinesN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r:   r>   rA   rY   r[   r6   r   r   r   r   r   r   r   †   s   !NOr   )Ú
__future__r   ÚmathZplotlyr   r   Zplotly.figure_factoryr   Zplotly.graph_objsr   Z
get_moduler	   r   Úpir#   Úobjectr   r   r   r   r   Ú<module>   s   
  ÿ
_