Kernel density estimation results in Grasshopper

A kernel density estimation implementation for Grasshopper

Kernel density estimation is a way of generating a smoothed function of density of a collection of data.

Randal Olson used Kernel density estimation to perform a statistical likelihood on the location of Waldo in the Where’s Waldo (Where’s Wally) books. Perhaps surprisingly, this didn’t reveal a random distribution, but showed that Waldo was more likely to appear in certain areas of the page.

The mathematics of kernel density estimation are closely linked to kernel smoothing, which I use a lot for my interpolation development. And since pretty much everything I do is in Grasshopper, I wanted to see if I could quickly implement KDE and make a few pretty pictures.

Output

Here, we can input and move a collection of points. In regions with high point density, the colour becomes more red.

And of course, making the most of the parametric capability of Grasshopper, we can move the points and get an updated Kernel Density Estimation in real time.

Grasshopper script

Kernel density estimation Grasshopper Rhino script

We input a mesh (or a Brep to convert to a mesh), which will provide our analysis surface for colouring later. We also input a list of data points.

A bit of C# then calculates the ‘score’ for each mesh point – or an estimation for the density over that mesh point. This returns a list of numbers. We can then colour the mesh according to these values.

The C# script – the ‘density’ component – contains the following code:

  private void RunScript(List<Point3d> pts, Mesh mesh, ref object A)
  {

    var rtnlist = new List<double>();

    foreach(var v in mesh.Vertices)
    {
      double tempval = 0;
      foreach (var pt in pts)
      {
        tempval += kernel(pt.DistanceTo(v), 0.2); //0.2 is a smoothing value - you can change this 
      }
      rtnlist.Add(tempval);
    }

    A = rtnlist;
  }

  // <Custom additional code> 

  public double kernel(double input, double factor)
  {
    return Math.Exp(-(factor * input));
  }

Gravity wells

The kernel density estimation can sometimes be thought of as a smoothed histogram. Another way to visualise regions of high density is to take advantage of the Z component and give our mesh some height.

To do this, I reconstructed each mesh point using the vertex score as an input for the mesh point Z component. So that the input mesh points are still easily visible, I multiplied these scores by -1. This gave a visualisation quite akin to a collection of gravity wells, the points perhaps being tiny planets floating in a 2D space.

The mesh can be modified by deconstructing the mesh and then deconstructing the points within this mesh. We then supply a modified Z value, then re-construct the mesh.

Kernel density estimation Grasshopper

3 thoughts on “A kernel density estimation implementation for Grasshopper”

  1. Thank you for sharing your work. You refer that this C# implementation is based on Randal Olson work. What I can’t figure is on what kernel function this kernel is based. Here is a list of kernel functions: https://en.m.wikipedia.org/wiki/Kernel_(statistics)

    I made a few changes to your code so that it is possible to control the bandwidth of the kernel function. By varying the factor is possible to compensate for different distributions of points in space.

    public double kernel(double input, double fator)
    {
    return Math.Exp(-(fator * input));
    }

  2. Super interesting. Thank you for this.
    Would you be able to elaborate a bit more how you got to this kernel function:
    Math.Exp(-(factor * input)); ?
    I saw the further comment and the link you sent, but I couldn’t quite follow…
    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.