def drawStreamLine_(axes, mesh, c, data, dataMesh=None, **kwargs): """ Draw a single streamline into a given mesh for given data stating at the center of cell c. The Streamline will be enlarged until she reached a cell that already contains a streamline. Parameters ---------- axes : matplotlib.axes axes to draw into mesh : :gimliapi:`GIMLI::Mesh` 2d Mesh to draw the streamline c : :gimliapi:`GIMLI::Cell` start cell data : iterable float | [float, float] If data is an array (per cell or node) gradients are calculated otherwise the data will be interpreted as vector field. dataMesh : :gimliapi:`GIMLI::Mesh` [None] Optional mesh for the data. If you want high resolution data to plot on coarse draw mesh. """ x, y = streamline(mesh, data, startCoord=c.center(), dLengthSteps=5, dataMesh=dataMesh, maxSteps=10000, verbose=False, koords=[0, 1]) if 'color' not in kwargs: kwargs['color'] = 'black' lines = None # print(len(x)) if len(x) > 2: lines = axes.plot(x, y, **kwargs) # updateAxes_(axes, lines) # print( x, y) # axes.plot(x, y, '.-', color='black', **kwargs) if len(x) > 3: xmid = int(len(x) / 2) ymid = int(len(y) / 2) dx = x[xmid + 1] - x[xmid] dy = y[ymid + 1] - y[ymid] c = mesh.findCell([x[xmid], y[ymid]]) dLength = c.center().dist(c.node(0).pos()) / 4. axes.arrow(x[xmid], y[ymid], dx, dy, width=dLength / 15., head_starts_at_zero=True, **kwargs) return lines
def drawStreamLine_(ax, mesh, c, data, dataMesh=None, linewidth=1.0, dropTol=0.0, **kwargs): """Draw a single streamline. Draw a single streamline into a given mesh for given data stating at the center of cell c. The Streamline will be enlarged until she reached a cell that already contains a streamline. TODO linewidth and color depends on absolute velocity or background color saturation Parameters ---------- ax : matplotlib.ax ax to draw into mesh : :gimliapi:`GIMLI::Mesh` 2d Mesh to draw the streamline c : :gimliapi:`GIMLI::Cell` start cell data : iterable float | [float, float] If data is an array (per cell or node) gradients are calculated otherwise the data will be interpreted as vector field. dataMesh : :gimliapi:`GIMLI::Mesh` [None] Optional mesh for the data. If you want high resolution data to plot on coarse draw mesh. linewidth : float [1.0] Streamline linewidth dropTol : float [0.0] Don't draw stream lines with velocity lower than drop tolerance. """ x, y, v = streamline(mesh, data, startCoord=c.center(), dLengthSteps=5, dataMesh=dataMesh, maxSteps=10000, verbose=False, coords=[0, 1]) if 'color' not in kwargs: kwargs['color'] = 'black' lines = None if len(x) > 2: points = np.array([x, y]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) lwidths = pg.RVector(len(v), linewidth) lwidths[pg.find(pg.RVector(v) < dropTol)] = 0.0 lines = mpl.collections.LineCollection( segments, linewidths=lwidths, **kwargs) ax.add_collection(lines) # probably the limits are wrong without plot call # lines = ax.plot(x, y, **kwargs) # updateAxes_(ax, lines) # ax.plot(x, y, '.-', color='black', **kwargs) if len(x) > 3: xmid = int(len(x) / 2) ymid = int(len(y) / 2) dx = x[xmid + 1] - x[xmid] dy = y[ymid + 1] - y[ymid] c = mesh.findCell([x[xmid], y[ymid]]) # dLength = c.center().dist(c.node(0).pos()) / 4. # NOT USED if v[xmid] > dropTol: # ax.arrow(x[xmid], y[ymid], dx, dy, # #width=dLength / 3., # width=0, # head_width=0.01, # head_length=0.02 # # head_width=dLength / 3., # # head_length=dLength / 3., # head_starts_at_zero=True, # length_includes_head=False, # lw=4, # ls=None, # **kwargs) dx90 = -dy dy90 = dx aLen = 3 aWid = 1 xy = list(zip([x[xmid] + dx90*aWid, x[xmid] + dx*aLen, x[xmid] - dx90*aWid], [y[ymid] + dy90*aWid, y[ymid] + dy*aLen, y[ymid] - dy90*aWid])) arrow = mpl.patches.Polygon(xy, ls=None, lw=0, closed=True, **kwargs) # arrow = mpl.collections.PolyCollection(xy, lines=None, # closed=True, **kwargs) ax.add_patch(arrow) return lines