rL i]dZddlZddlZddlmZmZmZddlm Z ddl m Z ddlmZdgZ ddZGddZGdd ZGd d ZGd d ZGddeZGddeZdZGddeZddZdZdZdZ y)z, Streamline plotting for 2D vector fields. N)_apicmpatches streamplotc  t||}t|}t||}|tjj }| |j } ||jj}|tjd}i}t| d| z}tjgd||dk(r|dz}t|tj }|rG|j"|j"k7r t%d gg}tj&j)|}n ||d <||d <t|tj r*|j"|j"k7r t%d g|d <n ||d <||d <||d <||d <|j"|j"k7s|j"|j"k7r t%dtj&j)|}tj&j)|}t+|||| ||}g}|]t-|j"D]C\}}|||fdk(s|j/||\}}||||} | 3|j1| En]tj2|t4j7}!|!D]t\}"}#|j8|"cxkr|j8|j:zkr2nn/|j<|#cxkr|j<|j>zkrbnt%d|"d|#d|!dddfxx|j8zcc<|!dddfxx|j<zcc<|!D]\}"}#|jA|"|#\}}tjB|d|jDdz }tjB|d|jFdz }||||} | p|j1| |rI| 2tIjJ|jM|jO} tQjR|}g}$g}%|D]0} | jT\}&}'|jW|&|'\}(})|(|j8z }(|)|j<z })t|tj s|rUtjX|(|)gj[ddd}*|$j]tj^|*dd|*ddgn(tjX|(|)g}*|$j1|*tj`tjbtjd|(tjd|)}+tjf|+|+ddz },|(|,|)|,f}-tjh|(|,|,dztjh|)|,|,dzf}.t|tj r,tk||&|'dd}/|d j]|/|/|,|d <|r5tk||&|'dd}0j1|0|| |0|,|d <tmjn|-|.fd| i|}1|%j1|13tqjr|$fd| i|}2|j8|j8|j:zg|2jtjvdd|j<|j<|j>zg|2jtjxdd|rP|2j{tj&j_|2j}||2j| |j|2tqj|%}3|%D]}1|j|1|jt|2|3}4|4S)a Draw streamlines of a vector flow. Parameters ---------- x, y : 1D/2D arrays Evenly spaced strictly increasing arrays to make a grid. If 2D, all rows of *x* must be equal and all columns of *y* must be equal; i.e., they must be as if generated by ``np.meshgrid(x_1d, y_1d)``. u, v : 2D arrays *x* and *y*-velocities. The number of rows and columns must match the length of *y* and *x*, respectively. density : float or (float, float) Controls the closeness of streamlines. When ``density = 1``, the domain is divided into a 30x30 grid. *density* linearly scales this grid. Each cell in the grid can have, at most, one traversing streamline. For different densities in each direction, use a tuple (density_x, density_y). linewidth : float or 2D array The width of the streamlines. With a 2D array the line width can be varied across the grid. The array must have the same shape as *u* and *v*. color : :mpltype:`color` or 2D array The streamline color. If given an array, its values are converted to colors using *cmap* and *norm*. The array must have the same shape as *u* and *v*. cmap, norm Data normalization and colormapping parameters for *color*; only used if *color* is an array of floats. See `~.Axes.imshow` for a detailed description. arrowsize : float Scaling factor for the arrow size. arrowstyle : str Arrow style specification. See `~matplotlib.patches.FancyArrowPatch`. minlength : float Minimum length of streamline in axes coordinates. start_points : (N, 2) array Coordinates of starting points for the streamlines in data coordinates (the same coordinates as the *x* and *y* arrays). zorder : float The zorder of the streamlines and arrows. Artists with lower zorder values are drawn first. maxlength : float Maximum length of streamline in axes coordinates. integration_direction : {'forward', 'backward', 'both'}, default: 'both' Integrate the streamline in forward, backward or both directions. data : indexable object, optional DATA_PARAMETER_PLACEHOLDER broken_streamlines : boolean, default: True If False, forces streamlines to continue until they leave the plot domain. If True, they may be terminated if they come too close to another streamline. Returns ------- StreamplotSet Container object with attributes - ``lines``: `.LineCollection` of streamlines - ``arrows``: `.PatchCollection` containing `.FancyArrowPatch` objects representing the arrows half-way along streamlines. This container will probably change in the future to allow changes to the colormap, alpha, etc. for both lines and arrows, but these changes should be backward compatible. Nzlines.linewidth ) arrowstylemutation_scale)bothforwardbackward)integration_directionr g@z?If 'color' is given, it must match the shape of the (x, y) gridcolorzCIf 'linewidth' is given, it must match the shape of the (x, y) grid linewidthzorderz3'u' and 'v' must match the shape of the (x, y) gridr)dtypezStarting point (z, z) outside of data boundaries transform)EGrid StreamMask DomainMapmlinesLine2Dr transData _get_linesget_next_colormplrcParamsdictr check_in_list isinstancenpndarrayshape ValueErrormamasked_invalid_get_integrator_gen_starting_points mask2gridappend asanyarrayfloatcopyx_originwidthy_originheight data2gridclipnxnymcolors Normalizeminmaxr _ensure_cmapT grid2data transposereshapeextendhstackcumsumhypotdiff searchsortedmean interpgridrFancyArrowPatch mcollectionsLineCollection sticky_edgesxy set_arrayset_cmapset_normadd_collectionPatchCollection add_patchautoscale_view StreamplotSet)5axesrNrOuvdensityrrcmapnorm arrowsizer minlengthrr start_points maxlengthrbroken_streamlinesgridmaskdmapline_kwarrow_kwuse_multicolor_lines line_colors integrate trajectoriesxmymxgygtsp2xsys streamlinesarrowstgxtgytxtypointssn arrow_tail arrow_head line_widths color_valuesplcacstream_containers5 [/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/matplotlib/streamplot.pyrrsR 1:D g D T4 D ~%%NN  }..0LL!23 Gz"y.IH6-BD&R %eRZZ8 ;;$** $/0 0d $$U+ !)RZZ( ??djj (89 9! (  )GHHX ww$**4:: 5NOO QA QA1dIy 57IL*4::6 +FBBF|q B/Bb"&89= ''*  +mmL6;;= 4FBMMRE4==4::+EEMMRF4==4;;+FF #3B4r">3"344 4 AqD T]]"  AqD T]]"  'FB^^B+FB Q! ,BQ! ,B"b"45A}##A& ' <$$UYY[%))+>Dt$K F !33SS)B dmm dmm i ,0D\\2r(+33B1=F   ryy&"+vabz)BC D\\2r(+F   v & IIbhhrwwr{BGGBK8 9 OOAqurz *eRU^ ggb1q5k*BGGBqQK,@A i ,$YS9#2>K K ' ' 4$/NH[ ! %eS#6s;L   | , $T,q/%: ;HW   # #   E.7 E;C E aC!F  $ $ 5( 5,3 5B MM4==4::+EFBOOa MM4==4;;+FGBOOa RUU\\+./ D D  % %f -B  q $R, ceZdZdZy)rWc ||_||_yN)linesru)selfrrus r__init__zStreamplotSet.__init__s  rN)__name__ __module__ __qualname__rrrrWrWsrrWcJeZdZdZdZdZdZdZdZd dZ dZ d d Z d Z y ) ra Map representing different coordinate systems. Coordinate definitions: * axes-coordinates goes from 0 to 1 in the domain. * data-coordinates are specified by the input x-y coordinates. * grid-coordinates goes from 0 to N and 0 to M for an N x M grid, where N and M match the shape of the input data. * mask-coordinates goes from 0 to N and 0 to M for an N x M mask, where N and M are user-specified to control the density of streamlines. This class also has methods for adding trajectories to the StreamMask. Before adding a trajectory, run `start_trajectory` to keep track of regions crossed by a given trajectory. Later, if you decide the trajectory is bad (e.g., if the trajectory is very short) just call `undo_trajectory`. cP||_||_|jdz |jdz z |_|jdz |jdz z |_d|jz |_d|j z |_d|jz |_ d|jz |_ y)Nr?) rcrdr7 x_grid2maskr8 y_grid2mask x_mask2grid y_mask2griddx x_data2griddy y_data2grid)rrcrds rrzDomainMap.__init__s   GGaKDGGaK8 GGaKDGGaK8 0 00 0 00<<rcbt||jzt||jzfS)z;Return nearest space in mask-coords from given grid-coords.)roundrrrxiyis r grid2maskzDomainMap.grid2mask#s-R$***+U28H8H3H-IIIrc>||jz||jzfSr)rr)rrlrms rr,zDomainMap.mask2grid'#D$$$b4+;+;&;;;rc>||jz||jzfSrrr)rxdyds rr5zDomainMap.data2grid*rrc>||jz ||jz fSrr)rrnros rr?zDomainMap.grid2data-rrch|j||\}}|jj|||yr)rrd_start_trajectoryrrnrorbrlrms rstart_trajectoryzDomainMap.start_trajectory0s-B'B ##B,>?rcT|j||\}}||f|j_yr)rrd _current_xy)rrnrorlrms rreset_start_pointzDomainMap.reset_start_point4s&B'B!#R rc|jj||st|j||\}}|jj |||yr)rc within_gridInvalidIndexErrorrrd_update_trajectoryrs rupdate_trajectoryzDomainMap.update_trajectory8sGyy$$R,# #B'B $$R-?@rc8|jjyr)rd_undo_trajectoryrs rundo_trajectoryzDomainMap.undo_trajectory>s ""$rNT) rrr__doc__rrr,r5r?rrrrrrrrrs7$ (J<<<@)A %rrc,eZdZdZdZedZdZy)rz Grid of data.ctj|dk(rnLtj|dk(r)|d}tj||s td|}n tdtj|dk(rnatj|dk(r>tj|}|d}tj||s td|}n tdtj |dkDj s tdtj |dkDj s td t||_t||_ |d|dz |_ |d|dz |_ |d|_ |d|_ |d |dz |_|d |dz |_tjtj ||j|jdz z s td tjtj ||j|jdz z s td y) NrrrzThe rows of 'x' must be equalz$'x' can have at maximum 2 dimensionsz The columns of 'y' must be equalz$'y' can have at maximum 2 dimensionsz'x' must be strictly increasingz'y' must be strictly increasingrz!'x' values must be equally spacedz!'y' values must be equally spaced)r$ndimallcloser'r@rFalllenr7r8rrr1r3r2r4)rrNrOx_rowyty_cols rrz Grid.__init__Ds 771:?  WWQZ1_aDE;;ua( !@AAACD D 771:?  WWQZ1_aBqEE;;ub) !CDDACD D Q##%>? ? Q##%>? ?a&a&A$1+A$1+! ! rUQqT\ eadl {{2771:tzzTWWq['AB@A A{{2771:t{{dggk'BC@A ADrc2|j|jfSr)r8r7rs rr&z Grid.shapeqswwrczd|cxkxr|jdz kncxrd|cxkxr|jdz kScS)z9Return whether (*xi*, *yi*) is a valid index of the grid.rr)r7r8rs rrzGrid.within_gridus9B%$''A+%@!r*@TWWq[*@@*@@rN)rrrrrpropertyr&rrrrrrBs&+BZ  Arrc2eZdZdZdZdZddZdZddZy) raN Mask to keep track of discrete regions crossed by streamlines. The resolution of this grid determines the approximate spacing between trajectories. Streamlines are only allowed to pass through zeroed cells: When a streamline enters a cell, that cell is set to 1, and no new streamlines are allowed to enter. c dtj|dzjt\|_|_|jdks|j dkr t dtj|j |jf|_|jj|_ d|_ y#t $r}t d|d}~wwxYw)Nrz,'density' must be a scalar or be of length 2rz'density' must be positive) r$ broadcast_toastypeintr7r8r'zeros_maskr&r)rr[errs rrzStreamMask.__init__s + "R__Wa%@ @HHM DGTW 77Q;$''A+9: :XXtww01 ZZ%%  +!"'* + +s9B77 C C  Cc |j|Sr)r)rargss r __getitem__zStreamMask.__getitem__szz$rc8g|_|j|||y)z%Start recording streamline trajectoryN)_trajrrrlrmrbs rrzStreamMask._start_trajectorys  B(:;rcD|jD]}d|j|<y)z#Remove current trajectory from maskrN)rr)rrps rrzStreamMask._undo_trajectorys" ADJJqM rc|j||fk7rK|||fdk(r8|jj||fd|j||f<||f|_y|rtyy)z Update current trajectory position in mask. If the new position has already been filled, raise `InvalidIndexError`. rrN)rrr-rrrs rrzStreamMask._update_trajectorysk   Bx 'BF|q  !!2r(+%& 2r6"$&8 %++ (rNr) rrrrrrrrrrrrrr|s    <  rrc eZdZy)rNrrrrrrrrrrc eZdZy)TerminateTrajectoryNrrrrrrrrrc2 j\jjdz z }jjdz z }tj j |dz|dzz  fd fd d  fd }|S)Nrrcjj||stt||}|dk(r t d|z }t||}t ||}||z||zfS)Nrr)rcr OutOfBoundsrIr) rrds_dtdt_dsuivirespeedrYrZs r forward_timez%_get_integrator..forward_timessyy$$R, 5"b) A:%' 'U  2r " 2r "Ez2:%%rc(||\}}| | fSrr)rrdxidyirs r backward_timez&_get_integrator..backward_times!B'StcTzrcdg}} j||| dvr#t|| |\}}||z }||dddz } dvr2j||t|| |\}}||z }||ddz }| kDr,t j |t j ddSjy#t$rYywxYw) a Return x, y grid-coordinates of trajectory based on starting point. Integrate both forward and backward in time from starting point in grid coordinates. Integration is terminated when a trajectory reaches a domain boundary or when it crosses into an already occupied cell in the StreamMask. The resulting trajectory is None if it is shorter than `minlength`. gN)r r r)r r r)rrr)rr_integrate_rk12rr$broadcast_arraysemptyr) x0y0rbstotalxy_trajr{xytrrerrrar_s rrjz"_get_integrator..integratesb   ! !"b*< = !$8 8$RT=)%79FAs aKF s4R4y G $7 7  " "2r *$RT<%79FAs aKF s12w G I &&w0@A!D D  "'!  sB99 CCr)r5rcr7r8r$r(sqrt) rYrZrer_raru_axv_axrjrrrs `````` @@@rr*r*s >>!Q DAq  q !D  q !D EEJJtqy419, -E &##J rc eZdZy)rNrrrrrrrrrcHd}td|jjz d|jjz d}|}d} |} |} g} |jj | | r| j | | fnt|| | \} }|| || zz| ||zz\}}|| z}||z}|dz| |zz}|dz||zz}|jj\}}tj||z |dz z ||z |dz z }||kr0| |z } | |z } |j| | || |z|kDr | | fS| |z } |dk(r|}nt|d|z||z dzz}#t$r| rt| ||\}} | |z } Y| | fSt$rY| | fSwxYw#t$rY| | fSwxYw)a 2nd-order Runge-Kutta algorithm with adaptive step size. This method is also referred to as the improved Euler's method, or Heun's method. This method is favored over higher-order methods because: 1. To get decent looking trajectories and to sample every mask cell on the trajectory we need a small timestep, so a lower order solver doesn't hurt us unless the data is *very* high resolution. In fact, for cases where the user inputs data smaller or of similar grid size to the mask grid, the higher order corrections are negligible because of the very fast linear interpolation used in `interpgrid`. 2. For high resolution input data (i.e. beyond the mask resolution), we must reduce the timestep. Therefore, an adaptive timestep is more suited to the problem as this would be very hard to judge automatically otherwise. This integrator is about 1.5 - 2x as fast as RK4 and RK45 solvers (using similar Python implementations) in most setups. g~jth?r皙?rg?rg333333?)r;rdr7r8rcrr-r _euler_steprr&r$rErr)rrrefrarbmaxerrormaxdsdsrrrxyf_trajk1xk1yk2xk2ydx1dy1dx2dy2r8r7errors rrrs-4H TYY\\!2 #4c :E B F B BH  yy$$R,R)!! RyHCb3hR#X 6HC3h3h3h#)$3h#)$B#)Q/#)Q1GH 8  #IB #IB &&r2/AB{Y& 8  bLF A:BUD2IE)9c(AABBc  *8T1= H"  > 8 =#  : 8 = $%  8  s+ AEF FFF F! F!cn|jj\}}|d\}}|||\}}|dk(rtj} n|dkr|| z } n |dz |z |z } |dk(rtj} n|dkr|| z } n |dz |z |z } t | | } |j ||| zz||| zzf| |fS)zBSimple Euler integration step that extends streamline to boundary.rrr)rcr&r$infr;r-) rrerr8r7rrcxcydsxdsyrs rrrbs YY__FB b\FB r2YFB Qwff aB3hAv{b  Qwff aB3hAv{b  S#B OOR"r'\2R<01 x<rctj|\}}t|tjre|j t }|j t }tj |dzd|dz }tj |dzd|dz }n6t |}t |}||dz k(r|}n|dz}||dz k(r|}n|dz}|||f} |||f} |||f} |||f} ||z } ||z }| d| z z| | zz}| d| z z| | zz}|d|z z||zz}t|tjs%tjj|rt|S)z0Fast 2D, linear interpolation on an integer gridrr) r$r&r#r%rrr6r( is_maskedr)arrNyNxrNrOxnyna00a01a10a11xtra0a1ais rrIrI{sfXXa[FB"bjj! IIcN IIcN WWQUArAv & WWQUArAv & G G a=BQB a=BQB AqD'C ArE(C BE(C BF)C aB aB B#( "B B#( "B q2vb B b"** % 55??2 % % Irc#2K|\}}d}d}|dz }|dz }d\}}d} t||zD]h} ||f| dk(r|dz }||k\s|dz}d} !| dk(r|dz }||k\s1|dz}d} 9| dk(r|dz}||ksI|dz }d} Q| dk(sW|dz}||ksb|dz }d} jyw) a Yield starting points for streamlines. Trying points on the boundary first gives higher quality streamlines. This algorithm starts with a point on the mask corner and spirals inward. This algorithm is inefficient, but fast compared to rest of streamplot. rr)rrrightupleftdownN)range) r&r8r7xfirstyfirstxlastylastrNrO directionis rr+r+sFB F F FE FE DAqI 27^$d   FAEz  $  FAEz " & FAF{! " & FAF{! # -$s$ABBB4 B B B)rNNNNrz-|>rNNNg@r Tr)!rnumpyr$ matplotlibrrrrmatplotlib.colorscolorsr9matplotlib.collections collectionsrKmatplotlib.linesrr__all__rrWrrr Exceptionrrr* IndexErrorrrrrIr+rrrr3s ((#-! .CG=BHL4:"& dN<%<%~7A7At33l   ) >B * ]@2%P%$r