1

I am trying to convey the concentration of lines in 2D space by showing the number of crossings through each pixel in a grid. I am picturing something similar to a density plot, but with more intuitive units. I was drawn to the spatstat package and its line segment class (psp) as it allows you to define line segments by their end points and incorporate the entire line in calculations. However, I'm struggling to find the right combination of functions to tally these counts and would appreciate any suggestions.

As shown in the example below with 50 lines, the density function produces values in (0,140), the pixellate function tallies the total length through each pixel and takes values in (0, 0.04), and as.mask produces a binary indictor of whether a line went through each pixel. I'm hoping to see something where the scale takes integer values, say 0..10.

require(spatstat)  
set.seed(1234)  
numLines = 50  

# define line segments
L = psp(runif(numLines),runif(numLines),runif(numLines),runif(numLines), window=owin())

# image with 2-dimensional kernel density estimate
D = density.psp(L, sigma=0.03)  

# image with total length of lines through each pixel  
P = pixellate.psp(L)  

# binary mask giving whether a line went through a pixel  
B = as.mask.psp(L)  

par(mfrow=c(2,2), mar=c(2,2,2,2))
plot(L, main="L")  
plot(D, main="density.psp(L)")  
plot(P, main="pixellate.psp(L)")  
plot(B, main="as.mask.psp(L)")

The pixellate.psp function allows you to optionally specify weights to use in the calculation. I considered trying to manipulate this to normalize the pixels to take a count of one for each crossing, but the weight is applied uniquely to each line (and not specific to the line/pixel pair). I also considered calculating a binary mask for each line and adding the results, but it seems like there should be an easier way. I know that you can sample points along a line, and then do a count of the points by pixel. However, I am concerned about getting the sampling right so that there is one and only one point per line crossing of a pixel.

Is there is a straight-forward way to do this in R? Otherwise would this be an appropriate suggestion for a future package enhancement? Is this more easily accomplished in another language such as python or matlab?

The example above and my testing has been with spatstat 1.40-0, R 3.1.2, on x86_64-w64-mingw32.

bph
  • 23
  • 8

1 Answers1

0

You are absolutely right that this is something to put in as a future enhancement. It will be done in one of the next versions of spatstat. It will probably be an option in pixellate.psp to count the number of crossing lines rather than measure the total length.

For now you have to do something a bit convoluted as e.g:

require(spatstat)  
set.seed(1234)  
numLines = 50  

# define line segments
L <- psp(runif(numLines),runif(numLines),runif(numLines),runif(numLines), window=owin())

# split into individual lines and use as.mask.psp on each
masklist <- lapply(1:nsegments(L), function(i) as.mask.psp(L[i]))

# convert to 0-1 image for easy addition
imlist <- lapply(masklist, as.im.owin, na.replace = 0)
rslt <- Reduce("+", imlist)

# plot
plot(rslt, main = "")

Number of lines crossing each pixel

Ege Rubak
  • 4,347
  • 1
  • 10
  • 18