Using DotNet-Interactive to render a scatter graph

Jupyter
Published

May 6, 2020

Using DotNet-Interactive to render a scatter graph

Sierpinski’s Gasket in DotNet-Interactive using Powershell

Sierpinski’s Gasket in DotNet-Interactive using Powershell

My goal is just to demonstrate how to use a scatter plot.

Initialization

I’ll define the following: * size of the axis * number of points I’ll generate * two arrays to hold the coordinates of the points * x-axis * y-axis * a marker use for plotting * the class I’ll use to track the current point * an instance tracking the current point

#Define the x and y axis max
$max = 100

#Define the number of points at which we will stop and render the chart
$pointCount = 20000

# Create the list of x and y location that the point landed on
$x = [System.Collections.Generic.List[Double]]::new($pointCount)
$y = [System.Collections.Generic.List[Double]]::new($pointCount)

# Define the x-axis for the plot
$xaxis = [XPlot.Plotly.Graph+Xaxis]::new()
$xaxis.showticklabels = $false
$xaxis.showgrid = $false
$xaxis.zeroline = $false

# Define the y-axis for the plot
$yaxis = [XPlot.Plotly.Graph+Yaxis]::new()
$yaxis.showticklabels = $false
$yaxis.showgrid = $false
$yaxis.zeroline = $false

# Define the marker for a point
$marker = [XPlot.Plotly.Graph+Marker]::new()
$marker.color = "rgb(34, 139, 37)"
$marker.Size = 2

# Define a class to track the point
class point {
    [double] $x=0
    [double] $y=0
}

# Create the current point
[point] $point = [point]::new()

Create the points

For sake of demo’ing this, well measure how long everything takes.

Well create a loop for the number of points we want to create. In the loop, we will create a direction with 3 possible values, If it’s the first, we will move the point half way towards 0, 0. If it’s the second, we will move the point half way towards, max,0. If it’s the third, we will move the point half way towards, 0,max. Then, add the point to the arrays, and loop.

When done with the loop, we will print the amount of time this process took.

# Create a look for the number of points to create
$seconds = (Measure-Command {
    foreach($i in 1..$pointCount) {

        # Get and random number to choose which direction to move
        $direction = Get-random -Minimum 0 -Maximum 3
        switch($direction){
            # if 0, move toward 0,0
            0{
                Write-Verbose "towards 0"
                $point.x= $point.x/2
                $point.y = $point.y/2
            }

            # if 1, move toward max,0
            1{
                Write-Verbose "towards xMax"
                $point.x= ($point.x+$max)/2
                $point.y = $point.y/2

            }

            # if 2, move toward 0,max
            2{
                Write-Verbose "towards yMax"
                $point.x= $point.x/2
                $point.y = ($point.y+$max)/2        
            }
        }

        # add the current point to the lists
        $x.Add($point.x)
        $y.Add($point.y)
    }
}).TotalSeconds

Write-Verbose -Message "data creation seconds: $seconds for $pointCount points" -Verbose
VERBOSE: data creation seconds: 3.035501 for 20000 points

Plotting the points

First, create a scattergl trace. Then, assing the x and y arrays of points coordinates to the traces properties. Then, set the mode to markers Then, set the marker to the marker we initialized earlier.

I’ll create a layout to make the plot a little bigger (550x550 is about the largest I could get it to reliably render in jupyter-lab.) Then, assign the y and x axis we created earlier to the apporiate properties. Then, use New-PlotlyChart to create the chart and Out-Display to render it.

Again, I print the time this took.

# Create the trace of the points
$seconds = (Measure-Command {
$p1 = [XPlot.Plotly.Graph+Scattergl]::new()
$p1.x  = $x.ToArray()
$p1.y  = $y.ToArray()
$p1.mode = "markers"
$p1.marker  = $marker

$layout = [XPlot.Plotly.Layout+Layout]::new()
$layout.width = 550
$layout.height = 550

$layout.xaxis = $xaxis
$layout.yaxis = $yaxis
# Render the chart
New-PlotlyChart -trace $p1 -Layout $layout  | Out-Display
}).TotalSeconds
Write-Verbose -Message "rendering seconds: $seconds" -Verbose
VERBOSE: rendering seconds: 0.2375148