
    -Ph8                         d dl Z d dlmZmZ d dlmZ d dlmZ  ej        d          Z	d Z
de j        dz  d	fd
Z G d de          ZdS )    N)
exceptionsoptional_imports)utils)
graph_objsnumpyc                    t           du rt          d          t          t          |           dz
            D ]@}| |dz            | |         z
  | d         | d         z
  z
  dk    rt	          j        d          At          t          |          dz
            D ]@}||dz            ||         z
  |d         |d         z
  z
  dk    rt	          j        d          Ad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indexs      a/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/plotly/figure_factory/_streamline.pyvalidate_streamliner   
   s     
U{{JKKKs1vvz""  uqy\AeH$1!5??(C   @ s1vvz""  uqy\AeH$1!5??(C   @     r	   	   g
ףp=
?c           	         t          j        | |           t          j        ||           t          | |           t          j        ||           t	          | ||||||                                          \  }}	t	          | ||||||                                          \  }
}t          j        d||
z   |	|z   dd|}|g}t          j	        d          }t          j
        ||          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layout )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   s                  r   create_streamliner1   %   s   R 
1%%%	1%%%1	#GMMMM!,	1aGUK" "o L, #	1aGUK  GW # 

 L7$: LR J <D333F$v6666r   c                   B    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
S )r"   zB
    Refer to FigureFactory.create_streamline() for docstring
    c                 L   t                               |          | _        t                               |          | _        t                               |          | _        t                               |          | _        || _        || _        t          d|z            | _	        | j        d         | j        d         z
  | _
        | j        d         | j        d         z
  | _        | j        | _        | j        | _        t                               | j	        | j	        f          | _        t!          | j                  t#          | j	        dz
            z  | _        t!          | j                  t#          | j	        dz
            z  | _        g | _        | j        | j        d         | j        d         z
  z  | _        | j        | j        d         | j        d         z
  z  | _        t                               | j        dz  | j        dz  z             | _        | xj        t!          | j                  z  c_        | xj        t!          | j                  z  c_        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_ys                r   __init__z_Streamline.__init__   s   !!!!
&2<((vay46!9,vay46!9,V
V
 XXt|T\:;;
TVuT\A-='>'>>TVuT\A-='>'>> 46":q	1246":q	12WWTVQY233
 	#df++#df++		%)%9%9%;%;"l!7799(((r   c                 j    t          || j        z  dz             t          || j        z  dz             fS )zQ
        Set up positions for trajectories to be used with rk4 function.
              ?)r8   r@   rA   )rH   xiyis      r   	blank_posz_Streamline.blank_pos   s7     R$.(C/00#rDN7Jc6Q2R2RSSr   c                 8   t          |t          j                  r?|                    t                    | _        |                    t                    | _        n(t	          |          | _        t	          |          | _        || j        | j        f         }|| j        | j        dz   f         }|| j        dz   | j        f         }|| j        dz   | j        dz   f         }|| j        z
  }|| j        z
  }	|d|z
  z  ||z  z   }
|d|z
  z  ||z  z   }|
d|	z
  z  ||	z  z   S )zK
        Set up for RK4 function, based on Bokeh's streamline code
        r	   )	
isinstancer
   ndarrayastyper8   r   r   r;   r<   )rH   arN   rO   a00a01a10a11xtyta0a1s               r   value_atz_Streamline.value_at   s    b"*%% 	!YYs^^DFYYs^^DFFRDJRDJ
DJ&'
DJN*+
Q
*+
Q
Q./$*_$*_AF^cBh&AF^cBh&QV}rBw&&r   c                      fd} fd} fdg g  fd} ||||          \  }}} ||||          \  }	}
}||	z   }|
ddd         |dd         z   }|ddd         |dd         z   }t          |          dk     rdS |dk    r)                     ||          \  }}d j        ||f<   ||fS t                    D ]\  }}d	 j        ||f<   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                     d                     j        | |          z  }                     j        | |          }                     j        | |          }||z  ||z  fS Ng      ?r^   rD   r(   r)   rN   rO   dt_dsuivirH   s        r   fz$_Streamline.rk4_integrate.<locals>.f   s`    $--
B;;;Etvr2..Btvr2..B:rEz))r   c                     d                     j        | |          z  }                     j        | |          }                     j        | |          }| |z  | |z  fS ra   rb   rc   s        r   gz$_Streamline.rk4_integrate.<locals>.g   sd    $--
B;;;Etvr2..Btvr2..B3;e++r   c                     d| cxk    ot          j                  dz
  k     nc o$d|cxk    ot          j                  dz
  k     nc S )Nr   r	   )r   r   r   )rN   rO   rH   s     r   <lambda>z+_Streamline.rk4_integrate.<locals>.<lambda>   s]    R 9 9 9 9#df++/ 9 9 9 9 Wa2>W>W>W>WDFVW>W>W>W>W r   c                 ^   d}d}| }|}                     ||          \  }}g }	g }
 ||          rv|	                    |           |
                    |           	  |||          \  }} ||d|z  |z  z   |d|z  |z  z             \  }} ||d|z  |z  z   |d|z  |z  z             \  }} ||||z  z   |||z  z             \  }}n# t          $ r Y nw xY w|||d|z  z   d|z  z   |z   z  dz  z  }|||d|z  z   d|z  z   |z   z  dz  z  } ||          sn||z  }                     ||          \  }}||k    s||k    rOj        ||f         dk    r;dj        ||f<                       |                               |           |}|}nn|dk    rn ||          v||	|
fS )Ng{Gz?r   rM   r6   g      @r	   )rP   append
IndexErrorr>   )x0y0rg   dsstotalrN   rO   xbybxf_trajyf_trajk1xk1yk2xk2yk3xk3yk4xk4ynew_xbnew_ybcheckrH   
xb_changes
yb_changess                        r   rk4z&_Streamline.rk4_integrate.<locals>.rk4   sQ   BFBB^^B++FBGG%B-- r"""r""" qRyyHC qcBhn!4b38c>6IJJHC qcBhn!4b38c>6IJJHC qb3hR#X>>HC!   EbC!c'MAG3c9:S@@bC!c'MAG3c9:S@@uR}} "!%B!7!7R<<6R<<z&&.1Q6656
66>2"))&111"))&111##A::5 %B-- 6 7G++s   A,C 
CCNr5   r	   g?r   )r   rP   r>   zip)rH   ro   rp   rg   ri   r   sfru   rv   sbxb_trajyb_trajrr   x_trajy_trajinitxbinitybrs   rt   r   r   r   s   `                  @@@r   rk4_integratez_Streamline.rk4_integrate   sr   	* 	* 	* 	* 	*	, 	, 	, 	, 	, YXXX

#	, #	, #	, #	, #	, #	, #	, #	,J  #s2r1~~GW"s2r1~~GWb2,2,v;;??4C<<!^^B33NFF)*DJvv~&6>!j*55 ' 'B%&
2r6""4r   c                     |dk     s|| j         k    s|dk     s|| j         k    rdS | j        ||f         dk    rD|                     || j        z  || j        z            }|| 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   r>   r   r@   rA   rB   rm   )rH   rs   rt   ts       r   trajz_Streamline.traj  s     66R4<''266R4<5G5GF:b"f""""2#6T^8KLLA}!((+++++ #"}r   c                     t           j        dz            D ]}t           j        d|z  z
            D ]|}                     ||z   |                                ||z    j        dz
  |z
                                  |||z                                    j        dz
  |z
  ||z              } fd j        D              _         fd j        D              _        t          t           j                            D ]S} j        |                                          j        |<    j        |                             t          j
                   Tt          t           j                            D ]S} j        |                                          j        |<    j        |                             t          j
                   TdS )z=
        Get streamlines by building trajectory set.
        r6   r	   c                 |    g | ]8}t                               |d                    j        z  j        d          z   9S )r   )r
   r7   r9   r   .0r   rH   s     r   
<listcomp>z/_Streamline.get_streamlines.<locals>.<listcomp>.  F     
 
 
:;BHHQqTNNT\)DF1I5
 
 
r   c                 |    g | ]8}t                               |d                    j        z  j        d         z   9S )r	   r   )r
   r7   r:   r   r   s     r   r   z/_Streamline.get_streamlines.<locals>.<listcomp>1  r   r   N)r   r   r   rB   rE   rF   r   tolistrm   r
   nan)rH   indentrN   r   s   `   r   rG   z_Streamline.get_streamlines#  s    DLA-.. 	B 	BFDL1v:566 B B		"v+v...		"v+t|a'7&'@AAA		&"v+...		$,*V3R&[AAAA	B
 
 
 
?C?P
 
 
	
 
 
 
?C?P
 
 
	 3ty>>** 	, 	,E#y/6688DIeIe##BF++++3ty>>** 	, 	,E#y/6688DIeIe##BF++++	, 	,r   c                  
   t                               t          | j                            }t                               t          | j                            }t                               t          | j                            }t                               t          | j                            }t          t          | j                            D ]}| j        |         t          t          | j        |                   dz                     ||<   | j        |         t          t          | j        |                   dz            dz
           ||<   | j        |         t          t          | j        |                   dz                     ||<   | j        |         t          t          | j        |                   dz            dz
           ||<   ||z
  }||z
  }t                                           }t                               dd           t           	                    ||z            }	t          j        di | |	| j
        z   }
|	| j
        z
  }t                               |
          | j        z  }t                               |
          | j        z  }t                               |          | j        z  }t                               |          | j        z  }t                               t          |                    }t                               t          |                    }t                               t          |                    }t                               t          |                    }t          t          |                    D ]}||         dk    rQ||         ||         z
  ||<   ||         ||         z
  ||<   ||         ||         z
  ||<   ||         ||         z
  ||<   _||         ||         z   ||<   ||         ||         z   ||<   ||         ||         z   ||<   ||         ||         z   ||<   t                               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   rE   rF   r   r8   geterrseterrarctanr*   cosr   sinr   r7   flattenr   )rH   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spacerI   rJ   s                          r   r$   z!_Streamline.get_streamline_arrows=  s/    hhDI00hhDI00#di..22#di..223ty>>** 	 	E!%5!1#c$)E:J6K6Ka6O2P2P!QK#'9U#3S5)**Q.//14$M%  "&5!1#c$)E:J6K6Ka6O2P2P!QK#'9U#3S5)**Q.//14$M%   m+m+99;;
		8	44455=11
	H,, 00 00 00 0088SZZ))88SZZ))88SZZ))88SZZ))3u::&& 
	E 
	EEU|q  "-e"4ve}"D"-e"4ve}"D"-e"4ve}"D"-e"4ve}"D"-e"4ve}"D"-e"4ve}"D"-e"4ve}"D"-e"4ve}"D#h--))6aaa 88X{HeDEE##C((??$$ 88X{HeDEE##C((??$$!!r   c                 ^    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
        )sumrE   rF   )rH   r,   r-   s      r   r#   z_Streamline.sum_streamlines  s1     49b))49b))\))r   N)__name__
__module____qualname____doc__rK   rP   r^   r   r   rG   r$   r#   r   r   r   r"   r"      s         : : :BT T T' ' '(L L L\, , ,", , ,4K" K" K"Z
* 
* 
* 
* 
*r   r"   )mathplotlyr   r   plotly.figure_factoryr   plotly.graph_objsr   
get_moduler
   r   pir1   objectr"   r   r   r   <module>r      s     / / / / / / / / ' ' ' ' ' ' ( ( ( ( ( (  ))  8 1$\7 \7 \7 \7~P* P* P* P* P*& P* P* P* P* P*r   