{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Volume Rendering {#volume_rendering_example}\n\nVolume render uniform mesh types like\n`pyvista.ImageData`{.interpreted-text role=\"class\"} or 3D NumPy arrays.\n\nThis also explores how to extract a volume of interest (VOI) from a\n`pyvista.ImageData`{.interpreted-text role=\"class\"} using the\n`pyvista.ImageDataFilters.extract_subset`{.interpreted-text role=\"func\"}\nfilter.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import pyvista as pv\nfrom pyvista import examples\n\n\n# Download a volumetric dataset\nvol = examples.download_knee_full()\nvol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Simple Volume Render\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# A nice camera position\ncpos = [(-381.74, -46.02, 216.54), (74.8305, 89.2905, 100.0), (0.23, 0.072, 0.97)]\n\nvol.plot(volume=True, cmap=\"bone\", cpos=cpos)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Opacity Mappings\n\nOr use the `pyvista.Plotter.add_volume`{.interpreted-text role=\"func\"}\nmethod like below. Note that here we use a non-default opacity mapping\nto a sigmoid:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pl = pv.Plotter()\npl.add_volume(vol, cmap=\"bone\", opacity=\"sigmoid\")\npl.camera_position = cpos\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use a custom opacity mapping\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "opacity = [0, 0, 0, 0.1, 0.3, 0.6, 1]\n\npl = pv.Plotter()\npl.add_volume(vol, cmap=\"viridis\", opacity=opacity)\npl.camera_position = cpos\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also use a shading technique when volume rendering with the\n`shade` option\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pl = pv.Plotter(shape=(1, 2))\npl.add_volume(vol, cmap=\"viridis\", opacity=opacity, shade=False)\npl.add_text(\"No shading\")\npl.camera_position = cpos\npl.subplot(0, 1)\npl.add_volume(vol, cmap=\"viridis\", opacity=opacity, shade=True)\npl.add_text(\"Shading\")\npl.link_views()\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Cool Volume Examples\n\nHere are a few more cool volume rendering examples.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Head Dataset\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "head = examples.download_head()\n\npl = pv.Plotter()\npl.add_volume(head, cmap=\"cool\", opacity=\"sigmoid_6\", show_scalar_bar=False)\npl.camera_position = [(-228.0, -418.0, -158.0), (94.0, 122.0, 82.0), (-0.2, -0.3, 0.9)]\npl.camera.zoom(1.5)\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bolt-Nut MultiBlock Dataset\n\n::: note\n::: title\nNote\n:::\n\nSee how we set interpolation to `'linear'` here to smooth out scalars of\neach individual cell to make a more appealing plot. Two actor are\nreturned by `add_volume` because `bolt_nut` is a\n`pyvista.MultiBlock`{.interpreted-text role=\"class\"} dataset.\n:::\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "bolt_nut = examples.download_bolt_nut()\n\npl = pv.Plotter()\nactors = pl.add_volume(bolt_nut, cmap=\"coolwarm\", opacity=\"sigmoid_5\", show_scalar_bar=False)\nactors[0].prop.interpolation_type = 'linear'\nactors[1].prop.interpolation_type = 'linear'\npl.camera_position = [(127.4, -68.3, 88.2), (30.3, 54.3, 26.0), (-0.25, 0.28, 0.93)]\ncpos = pl.show(return_cpos=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Frog Dataset\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "frog = examples.download_frog()\n\npl = pv.Plotter()\npl.add_volume(frog, cmap=\"viridis\", opacity=\"sigmoid_6\", show_scalar_bar=False)\npl.camera_position = [(929.0, 1067.0, -278.9), (249.5, 234.5, 101.25), (-0.2048, -0.2632, -0.9427)]\npl.camera.zoom(1.5)\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Extracting a VOI\n\nUse the `pyvista.ImageDataFilters.extract_subset`{.interpreted-text\nrole=\"func\"} filter to extract a volume of interest/subset volume to\nvolume render. This is ideal when dealing with particularly large\nvolumes and you want to volume render only a specific region.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Load a particularly large volume\nlarge_vol = examples.download_damavand_volcano()\nlarge_vol" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "opacity = [0, 0.75, 0, 0.75, 1.0]\nclim = [0, 100]\n\npl = pv.Plotter()\npl.add_volume(\n large_vol,\n cmap=\"magma\",\n clim=clim,\n opacity=opacity,\n opacity_unit_distance=6000,\n)\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Woah, that\\'s a big volume. We probably don\\'t want to volume render the\nwhole thing. So let\\'s extract a region of interest under the volcano.\n\nThe region we will extract will be between nodes 175 and 200 on the\nx-axis, between nodes 105 and 132 on the y-axis, and between nodes 98\nand 170 on the z-axis.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "voi = large_vol.extract_subset([175, 200, 105, 132, 98, 170])\n\npl = pv.Plotter()\npl.add_mesh(large_vol.outline(), color=\"k\")\npl.add_mesh(voi, cmap=\"magma\")\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ah, much better. Let\\'s now volume render that region of interest.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pl = pv.Plotter()\npl.add_volume(voi, cmap=\"magma\", clim=clim, opacity=opacity, opacity_unit_distance=2000)\npl.camera_position = [\n (531554.5542909054, 3944331.800171338, 26563.04809259223),\n (599088.1433822059, 3982089.287834022, -11965.14728669936),\n (0.3738545892415734, 0.244312810377319, 0.8947312427698892),\n]\npl.show()" ] } ], "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 }