Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible layering of plots? #62

Closed
ScottStetkiewicz opened this issue Jan 25, 2017 · 7 comments
Closed

Possible layering of plots? #62

ScottStetkiewicz opened this issue Jan 25, 2017 · 7 comments

Comments

@ScottStetkiewicz
Copy link

I actually just asked this question on StackExchange, but realized it would make more sense to post it directly here.

Is it possible to overlay ScatterD3 layers like in ggplot? I have a gorgeous PCA output using ScatterD3 that has all the interactivity I'm looking for (I love this package, by the way), but no vector loading arrows. It's possible to create the arrows, but they'd likely have to be added as a layer on top of the point scatterplot.

Is this possible? And if not, are there any workarounds to achieve this effect?

@juba
Copy link
Owner

juba commented Jan 26, 2017

Hi,

I'm not sure I understand correctly what you want to achieve, but I think it's possible to add arrows to your plots, if these arrows start from the origin. It's more an hack/workaround than something else, though : you'll have to add one line per arrow to your data data frame, and a type variable which would be "point" for points and "arrow" for arrows. Then specify this variable with the type_var argument.

I'm not sure this would really achieve what you want to do, though, and I agree that a real layering possibility would be much cleaner. I may implement this some time in the future, but it would require quite some work on the package code.

@ScottStetkiewicz
Copy link
Author

Sorry, I may not have been too clear with the question - this is what I'm trying to make with ScatterD3, but as you can see it has arrows AND points in the same plot.

I take it that this isn't currently possible, then?

@juba
Copy link
Owner

juba commented Jan 26, 2017

Well, technically you can :

points <- data.frame(x = runif(10, -2, 2), 
                     y = runif(10, -2, 2), 
                     color = c(1,1,1,2,2,2,3,3,3,3), 
                     lab = letters[1:10], 
                     type = rep("point", 10))
arrows <- data.frame(x = runif(5, -1, 1), 
                     y = runif(5, -1, 1), 
                     color = rep(NA, 5),
                     lab = LETTERS[1:5], 
                     type = rep("arrow", 5))
data <- rbind(points, arrows)

scatterD3(data, x = x, y = y,
          lab = lab, type_var = data$type)

But it won't mix well with colors and ellipses :

scatterD3(data, x = x, y = y,
          lab = lab, type_var = data$type,
          col_var = color)

@ScottStetkiewicz
Copy link
Author

You're absolutely right - I didn't even think to redefine "point" and "arrow".

Using FactoMineR to perform PCA and create dataframes...

out<-PCA(iris[,1:4],scale.unit = TRUE, graph=FALSE)
cc1<-data.frame(out$ind$coord)
cc2<-data.frame(out$var$coord)

Can't figure out why, but the loading arrows are all confined to within a circle with radius=1. This resizes them as a workaround.

varcoordz1 <- (cc2$Dim.1*3)
varcoordz2 <- (cc2$Dim.2*3)

Then, using the code you supplied and tweaked:

points <- data.frame(x = cc1$Dim.1, 
                     y = cc1$Dim.2,
                     color = iris$Species,
                     lab = row.names(iris), 
                     type = rep("point", 150))

arrows <- data.frame(x = varcoordz1, 
                     y = varcoordz2, 
                     color = "Blue",
                     lab = row.names(cc2), 
                     type = rep("arrow", 4))

data1 <- rbind(points, arrows)

scatterD3(data1, x = x, y = y,
          lab = lab, type_var = data1$type, col_var = color)

This indeed generates a PCA plot with interactivity, points colored by groupings and the vector loading arrows. I can't quite seem to figure out what's happening with the scaling using FactoMineR, but something's slightly off with the scales and such. But comparing the output of this code to that from say ggplot, it's got an identical distribution and form.

Two small issues with this:

  1. I'm struggling to get the arrows to appear black, but this may just be my brain not working well.
  2. If you have to define the number of points or arrows in the dataframe, that could make it messy when trying to reactively alter the data using shiny.

I'll keep tinkering away, but thanks so much for the help.

@juba
Copy link
Owner

juba commented Jan 27, 2017

Well, that's the intended behavior of a scaled PCA : variable coordinates will all be inside the unit circle. If you want to display both points and arrows (individuals and variables) in the same plot, you'll have to scale your variable coordinates by the square root of the corresponding eigenvalue for each axis.

For the issues you are mentioning :

  1. Yes, that's what I meant by "it will not mix well with colors and ellipses". You could create a custom value in your color variable and manually assign it to black, but that's another workaround...
  2. That should not be a problem, I think.

@ScottStetkiewicz
Copy link
Author

Can you elaborate on your workaround for point 1? I've tried pretty much everything I can think of (short of using colors, as I need to retain the factor variables of the color argument passed to col_var in the example above) to try and get the arrows to appear black (and also to not have them appear in the legend).

@juba
Copy link
Owner

juba commented Jan 29, 2017

Well, you can force your arrows to black by providing custom colors in the colors argument :

points <- data.frame(x = runif(10, -2, 2), 
                     y = runif(10, -2, 2), 
                     color = c(1,1,1,2,2,2,3,3,3,3), 
                     lab = letters[1:10], 
                     type = rep("point", 10))
arrows <- data.frame(x = runif(5, -1, 1), 
                     y = runif(5, -1, 1), 
                     color = rep(NA, 5),
                     lab = LETTERS[1:5], 
                     type = rep("arrow", 5))
data <- rbind(points, arrows)

scatterD3(data, x = x, y = y,
          lab = lab, type_var = data$type,
          col_var = color,
          colors = c("#FF0000", "#009900", "#000099", "#000000"))

Unfortunately, there's no way right now to hide your arrows color from the legend... I'll have to work on the package to make it more flexible, maybe during the following months.

@juba juba closed this as completed Oct 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants