{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Streamlines {#streamlines_example}\n\nIntegrate a vector field to generate streamlines.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This example generates streamlines of blood velocity. An isosurface of\nspeed provides context. The starting positions for the streamtubes were\ndetermined by experimenting with the data.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nimport pyvista as pv\nfrom pyvista import examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Carotid\n\nDownload a sample dataset containing a vector field that can be\nintegrated.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mesh = examples.download_carotid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the stream line filtering algorithm using random seed points inside\na sphere with radius of 2.0.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "streamlines, src = mesh.streamlines(\n return_source=True,\n max_time=100.0,\n initial_step_length=2.0,\n terminal_speed=0.1,\n n_points=25,\n source_radius=2.0,\n source_center=(133.1, 116.3, 5.0),\n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Display the results. Please note that because this dataset\\'s velocity\nfield was measured with low resolution, many streamlines travel outside\nthe artery.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "p = pv.Plotter()\np.add_mesh(mesh.outline(), color=\"k\")\np.add_mesh(streamlines.tube(radius=0.15))\np.add_mesh(src)\np.add_mesh(mesh.contour([160]).extract_all_edges(), color=\"grey\", opacity=0.25)\np.camera_position = [(182.0, 177.0, 50), (139, 105, 19), (-0.2, -0.2, 1)]\np.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Blood Vessels\n\nHere is another example of blood flow:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mesh = examples.download_blood_vessels().cell_data_to_point_data()\nmesh.set_active_scalars(\"velocity\")\nstreamlines, src = mesh.streamlines(\n return_source=True,\n source_radius=10,\n source_center=(92.46, 74.37, 135.5),\n)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "boundary = mesh.decimate_boundary().extract_all_edges()\n\nsargs = dict(vertical=True, title_font_size=16)\np = pv.Plotter()\np.add_mesh(streamlines.tube(radius=0.2), lighting=False, scalar_bar_args=sargs)\np.add_mesh(src)\np.add_mesh(boundary, color=\"grey\", opacity=0.25)\np.camera_position = [(10, 9.5, -43), (87.0, 73.5, 123.0), (-0.5, -0.7, 0.5)]\np.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A source mesh can also be provided using the\n`pyvista.DataSetFilters.streamlines_from_source`{.interpreted-text\nrole=\"func\"} filter, for example if an inlet surface is available. In\nthis example, the inlet surface is extracted just inside the domain for\nuse as the seed for the streamlines.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "source_mesh = mesh.slice('z', origin=(0, 0, 182)) # inlet surface\n# thin out ~40% points to get a nice density of streamlines\nseed_mesh = source_mesh.decimate_boundary(0.4)\nstreamlines = mesh.streamlines_from_source(seed_mesh, integration_direction=\"forward\")\n# print *only* added arrays from streamlines filter\nprint(\"Added arrays from streamlines filter:\")\nprint([array_name for array_name in streamlines.array_names if array_name not in mesh.array_names])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot streamlines colored by the time along the streamlines.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "sargs = dict(vertical=True, title_font_size=16)\np = pv.Plotter()\np.add_mesh(\n streamlines.tube(radius=0.2),\n scalars=\"IntegrationTime\",\n clim=[0, 1000],\n lighting=False,\n scalar_bar_args=sargs,\n)\np.add_mesh(boundary, color=\"grey\", opacity=0.25)\np.add_mesh(source_mesh, color=\"red\")\np.camera_position = [(10, 9.5, -43), (87.0, 73.5, 123.0), (-0.5, -0.7, 0.5)]\np.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Kitchen\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "kpos = [(-6.68, 11.9, 11.6), (3.5, 2.5, 1.26), (0.45, -0.4, 0.8)]\n\nmesh = examples.download_kitchen()\nkitchen = examples.download_kitchen(split=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "streamlines = mesh.streamlines(n_points=40, source_center=(0.08, 3, 0.71))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "p = pv.Plotter()\np.add_mesh(mesh.outline(), color=\"k\")\np.add_mesh(kitchen, color=True)\np.add_mesh(streamlines.tube(radius=0.01), scalars=\"velocity\", lighting=False)\np.camera_position = kpos\np.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Custom 3D Vector Field\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nx = 20\nny = 15\nnz = 5\n\norigin = (-(nx - 1) * 0.1 / 2, -(ny - 1) * 0.1 / 2, -(nz - 1) * 0.1 / 2)\nmesh = pv.ImageData(dimensions=(nx, ny, nz), spacing=(0.1, 0.1, 0.1), origin=origin)\nx = mesh.points[:, 0]\ny = mesh.points[:, 1]\nz = mesh.points[:, 2]\nvectors = np.empty((mesh.n_points, 3))\nvectors[:, 0] = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)\nvectors[:, 1] = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)\nvectors[:, 2] = np.sqrt(3.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) * np.sin(np.pi * z)\n\nmesh['vectors'] = vectors" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "stream, src = mesh.streamlines(\n 'vectors',\n return_source=True,\n terminal_speed=0.0,\n n_points=200,\n source_radius=0.1,\n)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "cpos = [(1.2, 1.2, 1.2), (-0.0, -0.0, -0.0), (0.0, 0.0, 1.0)]\nstream.tube(radius=0.0015).plot(cpos=cpos)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 0 }