o
    d8                     @   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u rtdtt| d D ]}| |d  | |  | d | d   dkr+tdqtt|d D ]}||d  ||  |d |d   dkrOtdq4d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   PlotlyError)xyindex r   f/var/www/html/visualizacion-main/env/lib/python3.10/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d||
 |	| 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   modeclosest)	hovermode)datalayoutNr   )r   validate_equal_lengthr   validate_positive_scalars_Streamlinesum_streamlinesget_streamline_arrowsr   ScatterLayoutFigure)r   r   uvr   angler   kwargsstreamline_xstreamline_yarrow_xarrow_y
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_y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.
              ?)r3   r;   r<   )rC   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	   ndarrayastyper3   r   r   r6   r7   )rC   arH   rI   a00a01a10a11xtyta0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 rWd	S |dkrn||\}}dj||f< ||fS tD ]\}}dj||f< qsd	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      ?rW   r?   r%   r&   rH   rI   dt_dsuivirC   r   r   f   s   z$_Streamline.rk4_integrate.<locals>.fc                    sH   d   j| | }   j| |}   j| |}| | | | fS rX   rY   rZ   r^   r   r   g   s   z$_Streamline.rk4_integrate.<locals>.gc                    sD   d|   kot  jd k n  o!d|  kot  jd k S   S )Nr   r   )r   r   r   )rH   rI   r^   r   r   <lambda>   s   D z+_Streamline.rk4_integrate.<locals>.<lambda>c                    s  d}d}| }|} ||\}}g }	g }
 ||r|	| |
| z>|||\}}||d| |  |d| |  \}}||d| |  |d| |  \}}||||  |||  \}}W n	 tyj   Y niw |||d|  d|  |  d 7 }|||d|  d|  |  d 7 } ||sn>||7 } ||\}}||ks||krɈj||f dkrdj||f< | | |}|}nn
|dkrn ||s||	|
fS )Ng{Gz?r   rG   r1   g      @r   )rJ   append
IndexErrorr9   )x0y0r_   dsstotalrH   rI   xbybxf_trajyf_trajk1xk1yk2xk2yk3xk3yk4xk4ynew_xbnew_ybcheckrC   
xb_changes
yb_changesr   r   rk4   sH   


&&"$$




z&_Streamline.rk4_integrate.<locals>.rk4Nr0   r   g?r   )r   rJ   r9   zip)rC   rd   re   r_   r`   rz   sfrj   rk   sbxb_trajyb_trajrg   x_trajy_trajinitxbinitybrh   ri   r   rv   r   rk4_integrate   s(   %z_Streamline.rk4_integratec                 C   sr   |dk s|| j ks|dk s|| j krdS | j||f dkr5| || j || j }|dur7| j| dS dS 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   r9   r   r;   r<   r=   rb   )rC   rh   ri   tr   r   r   traj  s   $
z_Streamline.trajc                    s$  t  jd D ]8}t  jd|  D ],} || |  ||  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
 qzdS )z=
        Get streamlines by building trajectory set.
        r1   r   c                    s*   g | ]}t |d   j  jd   qS )r   )r	   r2   r4   r   .0r   r^   r   r   
<listcomp>0      z/_Streamline.get_streamlines.<locals>.<listcomp>c                    s*   g | ]}t |d   j  jd  qS )r   r   )r	   r2   r5   r   r   r^   r   r   r   3  r   N)r   r   r   r=   r@   rA   r   tolistrb   r	   nan)rC   indentrH   r   r   r^   r   rB   %  s(   

z_Streamline.get_streamlinesc                 C   s  t t| j}t t| j}t t| j}t t| j}tt| jD ]N}| j| tt| j| d  ||< | j| tt| j| d d  ||< | j| tt| j| d  ||< | j| tt| j| d d  ||< q'|| }|| }t  }t jddd t 	|| }	t jdi | |	| j
 }
|	| j
 }t |
| j }t |
| j }t || j }t || j }t t|}t t|}t t|}t t|}tt|D ]Z}|| dkr|| ||  ||< || ||  ||< || ||  ||< || ||  ||< q|| ||  ||< || ||  ||< || ||  ||< || ||  ||< qt t|}t j|dd< t ||||g}|d}| }t ||||g}|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Fr   )r	   emptyr   r@   rA   r   r3   geterrseterrarctanr'   cosr   sinr   r2   flattenr   )rC   arrow_end_xarrow_end_yarrow_start_xarrow_start_yr   dif_xdif_yorig_errstreamline_angang1ang2seg1_xseg1_yseg2_xseg2_ypoint1_xpoint1_ypoint2_xpoint2_yspacerD   rE   r   r   r   r!   ?  s`   $$




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
        )sumr@   rA   )rC   r)   r*   r   r   r   r      s   z_Streamline.sum_streamlinesN)__name__
__module____qualname____doc__rF   rJ   rW   r   r   rB   r!   r    r   r   r   r   r      s    !NMr   )
__future__r   mathplotlyr   r   plotly.figure_factoryr   plotly.graph_objsr   
get_moduler	   r   pir.   objectr   r   r   r   r   <module>   s    

_