Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert an image into point data for ggplot2 scatterplot

I recently found a package on Github where the dev analyzed fan-curated data on the 248 installments of the Spy vs Spy comic by Antonio Prohias appearing in Mad Magazine.

He goes through some basic exploratory data analysis, computes a running net score of Black Spy victories and then runs a non-parametric test (Wald Wolfowitz test) to look at clusters of consecutive victories by one of the Spies in order to ascertain if Prohias kept the score balance by reversing the previous outcome, or if he perhaps picked favorites.

While I found it a fun exercise I was most interested in the Spy Plot.

Spy Vs. Spy

The point data for the Spy Plot actually came from a MATLAB easter egg spy() package and the dev put this point data into R as a tibble::tribble.

My question is how can one create point data from an image? Is it possible to do edge detection in R with imager() to get an outline

enter image description here

And then somehow convert this image data into into a tbl_df? I'm unfamiliar with bitmap arrays but perhaps the answer lies in something like this?

like image 468
Matthew J. Oldach Avatar asked Jan 25 '18 10:01

Matthew J. Oldach


People also ask

How do you plot points on a scatter plot?

Draw a graph with the independent variable on the horizontal axis and the dependent variable on the vertical axis. For each pair of data, put a dot or a symbol where the x-axis value intersects the y-axis value. (If two dots fall together, put them side by side, touching, so that you can see both.)

How do you make a scatter plot from a dataset in R?

A scatter plot can be created using the function plot(x, y). The function lm() will be used to fit linear models between y and x. A regression line will be added on the plot using the function abline(), which takes the output of lm() as an argument. You can also add a smoothing line using the function loess().


1 Answers

We can use imager::cannyEdges to get the edges, then put the coordinates in a data frame to plot.

library('ggplot2')
library('imager')

plot(boats)

boats

img <- cannyEdges(boats)
plot(img)

edges

It looks like img is a logical array with 4 dimensions.

dim(img)
# [1] 256 384   1   3

I just want two dimensions, so I'll discard two of the dimensions.

img <- img[, , 1, 1]
img[1:8, 1:8]
#       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]
# [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [3,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [7,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

which can convert this matrix into a list of coordinates.

coords <- which(img, arr.ind = T)
head(coords)
#      row col
# [1,] 255   1
# [2,] 255   2
# [3,] 255   3
# [4,] 255   4
# [5,] 255   5
# [6,] 255   6

Now it can be plotted.

df <- data.frame(x = coords[,1], y = coords[,2])

ggplot(df, aes(x, -y)) +
  geom_point()

enter image description here

like image 200
Paul Avatar answered Oct 18 '22 02:10

Paul