{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Scaled Gaussian Points {#plot_spheres_example}\n\nThis example demonstrates how to plot spheres using the\n`'points_gaussian'` style and scale them by a dynamic radius.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\n\nimport pyvista as pv"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, generate the sphere positions and radii randomly on the edge of a\ntorus.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "N_SPHERES = 10_000\ntheta = np.random.default_rng().uniform(0, 2 * np.pi, N_SPHERES)\nphi = np.random.default_rng().uniform(0, 2 * np.pi, N_SPHERES)\ntorus_radius = 1\ntube_radius = 0.3\nradius = torus_radius + tube_radius * np.cos(phi)\nrad = np.random.default_rng().random(N_SPHERES) * 0.01\n\npos = np.zeros((N_SPHERES, 3))\npos[:, 0] = radius * np.cos(theta)\npos[:, 1] = radius * np.sin(theta)\npos[:, 2] = tube_radius * np.sin(phi)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next, create a PolyData object and add the sphere positions and radii as\ndata arrays.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pdata = pv.PolyData(pos)\npdata['radius'] = rad"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, plot the spheres using the `points_gaussian` style and scale\nthem by radius.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pl = pv.Plotter()\nactor = pl.add_mesh(\n    pdata,\n    style='points_gaussian',\n    emissive=False,\n    render_points_as_spheres=True,\n    show_scalar_bar=False,\n)\nactor.mapper.scale_array = 'radius'\npl.camera.zoom(1.5)\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Show the same plot with `emissive=True`.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pl = pv.Plotter()\npl.background_color = 'k'\nactor = pl.add_mesh(\n    pdata,\n    style='points_gaussian',\n    emissive=True,\n    render_points_as_spheres=True,\n    show_scalar_bar=False,\n)\nactor.mapper.scale_array = 'radius'\npl.camera.zoom(1.5)\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
}