Is it possible to overlay multiple layers of ScatterD3 plots on top of one another? I haven't been able to find this anywhere in either the vignettes or searching StackExchange/Google.
I'm curious, since folks have been able to make PCA Vector Loading plots using ScatterD3. If one could overlay this on top of another plot with the points (akin to what's possible with ggplot2 or ggvis layers), you could have a gorgeous and interactive PCA plot. Additionally, you might be able to outline points (since point stroke currently isn't an option).
Does anyone have any insight or workarounds?
It is possible, but more difficult. I would recommend using plotly package. You'll be able to use the View tab in the RStudio and more easily examine your 3D scatter by rotating. The color scheme is also easier to add This post attempts to tackle a similar, though not identical. A good (free) tutorial for plotly can be found here through DataCamp.
Question answered here thanks to the author of ScatterD3. To generate a full PCA plot, you need to redefine the dataframe being plotted like so:
library(FactoMineR)
library (ScatterD3)
out<-PCA(iris[,1:4],scale.unit = TRUE, graph=FALSE)
cc1<-data.frame(out$ind$coord)
cc2<-data.frame(out$var$coord)
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 = cc2$Dim.1,
y = cc2$Dim.2,
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)
Related
This is a ggplot produced by fviz_cluster function. The problem is that I want to single out some data points or even a single one and label it by name. I can easily identify the data points that are on the edges, but what happens for those in the middle of the pack. I thought of approaching this by labelling every data point and then zoom in, but the plot is not interactive and I can't find a way to do that. Any idea on how to approach this would be much appreciated
Here is my code:
r=as.data.frame(colnames(df))
remov=c(1,2,5,7,11,14,16,21,23,24,25,26,89,29:54)
df=df[,-remov]
rem=c(2,3,6,7,8,9,12,13,14,15,16)
rownam=as.data.frame(unique(df$Name))
k=df[,-rem]
k= k[!duplicated(df$Name),]
k <- data.frame(k[,-1], row.names = k[,1])
k=na.omit(k)
kme=kmeans(k,centers = 6,nstart = 25)
str(kme)
fviz_cluster(kme, data = k,geom="point")
If you want an easy workaround to make your graph interactive use the ggplotly() function.
install plotly:
install.packages("plotly")
library(plotly)
plot <- fviz_cluster(kme, data = k,geom="point")
plot %>% ggplotly()
# or
ggplotly(plot)
I am trying to use ggbio to plot gene transcripts. I want to plot a very specific range so it matches my ggplot2 plots. The problem is my example plot ends up having range of 133,567,500-133,570,000 regardless of the GRange and whether I specify xlim or not.
This example should only plot a small bit of intron (the thin arrowed line) but instead plots the full 2 exons and intron in between. I believe autoplot wants to plot the entire transcript or transcripts present in the range and widens the range to accommodate for that.
library(EnsDb.Hsapiens.v86)
library(ggbio)
ensdb <- EnsDb.Hsapiens.v86
mut<-GRanges("10", IRanges(133568909, 133569095))
gene <- autoplot(ensdb, which=mut, names.expr="gene_name",xlim=c(133568909,133569095))
gene.gg <- gene#ggplot
png("test_gene_plot_5.png")
gene.gg
dev.off()
Is there any way to over-ride this? I've looked at the manual page for autoplot and I couldn't narrow down an option that would fix it. Others have said to use xlim, but that does not seem to change anything
I like ggbio because it can make a ggplot2 object to be plotted along with other ggplot2 objects. I have not seen an example for that with other approaches like Gvis. But I would entertain other approaches if they could be combined with my existing plots.
Thanks!
Amy
It kind of depends wether you want clipped or squished data. Usually autoplot outputs a ggplot object at some point that can be manipulated as such.
For squished data:
library(GenomicRanges) # just to be sure start and end work
gene#ggplot +
scale_x_continuous(limits = c(start(mut), end(mut)), oob = scales::squish)
For clipped data:
gene#ggplot +
coord_cartesian(xlim = c(start(mut), end(mut)))
But to be totally honest, I'm unsure wether this is the most informative way to communicate that you are plotting the internals of an intron.
Alternatively, I've written a gene model geom at some point that doesn't work through the autoplot methods (which can sometimes be a pain if you want to customise everything). Downside is that you'd have to do some manual gene searching and setting aesthetics. Upside is that it works like most other geoms and is therefore easy to combine with some other data.
library(ggnomics) # from: https://github.com/teunbrand/ggnomics
# Finding a gene's exons manually
my_gene <- transcriptsByOverlaps(EnsDb.Hsapiens.v86, mut)
my_gene <- exonsByOverlaps(EnsDb.Hsapiens.v86, my_gene)
my_gene <- as.data.frame(my_gene)
some_other_data <- data.frame(
x = seq(start(mut), end(mut), by = 10),
y = cumsum(rnorm(19))
)
ggplot(some_other_data) +
geom_line(aes(x, y)) +
geom_genemodel(data = my_gene,
aes(xmin = start, xmax = end,
y = max(some_other_data$y) + 1,
group = 1, strand = strand)) +
coord_cartesian(xlim = c(start(mut), end(mut)))
Hope that helped!
I have 23 different groups,each of them consists of from 7 to 20 individual samples (totally approximately 350-400 observations) with their own x,y & z coordinates. I'd like to produce 3D plot based on the data i have by means of plot3d function of rgl R package. It's not a big deal in general. The problem, that i'd like to make each one from the mentioned above 23 groups to be easy distinguishable on the 3D plot. I tried to use different colors for each group, but unfortunately it's not possible to find a 23 well recognizable by human eyes colors. I was thinking about pch parameter like in the plot function of base R library. But, again, as i can see there is not such option in the plot3d function. Besides, i have to explain, that there are too much points in my data set and adding the labels to each point (e.g. with text3d rgl function) is not a good idea (they will overlap with each other and give in result some kind of a mess on the 3D plot). Is there way to figure out it (i gues it's very common problem)? Thank you in advance!
Below is code of some toy example for better explanation:
# generate data
prefix=rep("ID",69)
suffix=rep(1:23,3)
suffix_2=as.character(suffix[order(suffix)])
titles_1=paste(prefix,suffix,sep="_")
titles_2=titles_1[order(titles_1)]
x=1:69
y=x+20
z=x+50
df=data.frame(titles_2,x,y,z)
# load rgl library
library('rgl')
# make 3D plot
plot3d(x,y,z)
If you like living on the bleeding edge, there's a new function rgl::pch3d() that draws symbols using the same codes as points() does
in base graphics. It's in rgl 0.95.1475, available on R-forge (and within a few hours on Github; see How do I install the latest version of rgl?). It's not completely working with rglwidget() yet.
The example code
open3d()
i <- 0:25; x <- i %% 5; y <- rep(0, 26); z <- i %/% 5
pch3d(x, y, z, pch = i, bg = "green")
text3d(x, y, z + 0.3, i)
pch3d(x + 5, y, z, pch = LETTERS[i+1])
text3d(x + 5, y, z + 0.3, i+65)
produces this display (after some resizing and rotation):
It's not perfect, but how about using letters a-w to distinguish the groups?
with(df,plot3d(x,y,z))
with(df,text3d(x,y,z,texts=letters[titles_2]))
Because i'm going to use the 3D plot for publication purposes i used this solution for now. It's not pretended to be the best one.
# generate data
prefix=rep("ID",69)
suffix=rep(1:23,3)
suffix_2=as.character(suffix[order(suffix)])
titles_1=paste(prefix,suffix,sep="_")
titles_2=titles_1[order(titles_1)]
x=1:69
y=x+20
z=x+50
df=data.frame(titles_2,x,y,z)
# load rgl library
library('rgl')
# load randomcoloR library
library(randomcoloR)
# create a custom palette
palette <- distinctColorPalette(23)
palette(palette)
# make 3D plot
plot3d(x,y,z,size = 10,col=suffix[order(suffix)])
I am plotting some surfaces in R using the lattice package. I can't find a way to choose the colours of the surface. Here is an example:
Here is an example of how i plot each:
theseCol=heat.colors(150)
mm=paste("WB numbers where present\n(",nstoch," sims)",sep="")
WBnumbers=wbPrev_series
rownames(WBnumbers)=KList
colnames(WBnumbers)=iMwbList
wireframe(WBnumbers, zlim=c(0,max(wbPrev_series,na.rm=TRUE)), colorkey=FALSE,
col.regions=theseCol, scales = list(arrows = FALSE), drape = TRUE,
main=mm, zlab="", xlab="K", ylab="iMwb")
I would like for the first surface to be as it is, but for the others to be coloured not by their z levels but by the 1st surface's z levels. I tried multiple things but wireframe always accepts the colours i give as the possible ranges for the current variable.
Anyway this could be done?
Thanks
Here is the answer Dave W. posted some years back on the R-help mailing list. You probably can google up the entire thread.
From: David Winsemius
Following the advice in help(wirefrane) you need to look at the
levelplot section for advice re: a proper specification to colorkey
and follow the appropriate links in the help pages. Whether your data
is a proper input to wireframe cannot be determined from the included
information, although I suppose your reported success suggests it is.
This is an untested (since there was nothing to test) wild-assed guess
after reading the material I pointed to:
wireframe(data.m,aspect = c(0.3), shade=TRUE, screen = list(z = 0, x =
-45),
light.source = c(0,0,10), distance =
0.2,zlab="Freq",xlab="base",ylab="Fragment",
col=level.colors(x, at = do.breaks(range(data.m), 30),
col.regions = colorRampPalette(c("red", "white",
"blue")(30))
)
EDIT:
Per Josh's request, I played around a bit. The following will apply color shading (drape):
wireframe(dmat,drape=TRUE,col='black',col.regions = colorRampPalette(c("red", "white", "blue"))(30) )
Which sets the "drape" colors but not the gridlines themselves.
It's a darn shame that wireframe doesn't respect par(new=TRUE), because if it did we could slice the data matrix into z-ranges and overplot one color at a time.
I will have to check my "archive" of old experiments w/ R graphics when I get home, but I think I ended up using the scatterplot3d package to get data-dependent grid colors.
I generate a plot using the package hexbin:
# install.packages("hexbin", dependencies=T)
library(hexbin)
set.seed(1234)
x <- rnorm(1e6)
y <- rnorm(1e6)
hbin <- hexbin(
x = x
, y = y
, xbin = 50
, xlab = expression(alpha)
, ylab = expression(beta)
)
## Using plot method for hexbin objects:
plot(hbin, style = "nested.lattice")
abline(h=0)
This seems to generate an S4 object (hbin), which I then plot using plot.
Now I'd like to add a horizontal line to that plot using abline, but unfortunately this gives the error:
plot.new has not yet been called
I have also no idea, how I can manipulate e.g. the position of the axis labels (alpha and beta are within the numbers), change the position of the legend, etc.
I'm familiar with OOP, but so far I could not find out how plot() handles the object (does it call certain methods of the object?) and how I can manipulate the resulting plot.
Why can't I simply draw a line onto the plot?
How can I manipulate axis labels?
Use lattice version of hex bin - hexbinplot(). With panel you can add your line, and with style you can choose different ways of visualizing hexagons. Check help for hexbinplot for more.
library(hexbin)
library(lattice)
x <- rnorm(1e6)
y <- rnorm(1e6)
hexbinplot(x ~ y, aspect = 1, bins=50,
xlab = expression(alpha), ylab = expression(beta),
style = "nested.centroids",
panel = function(...) {
panel.hexbinplot(...)
panel.abline(h=0)
})
hexbin uses grid graphics, not base. There is a similar function, grid.abline, which can draw lines on plots by specifying a slope and intercept, but the co-ordinate system used is confusing:
grid.abline(325,0)
gets approximately what you want, but the intercept here was found by eye.
You will have more luck using ggplot2:
library(ggplot2)
ggplot(data,aes(x=alpha,y=beta)) + geom_hex(bins=10) + geom_hline(yintercept=0.5)
I had a lot of trouble finding a lot of basic plot adjustments (axis ranges, labels, etc.) with the hexbin library but I figured out how to export the points into any other plotting function:
hxb<-hexbin(x=c(-15,-15,75,75),
y=c(-15,-15,75,75),
xbins=12)
hxb#xcm #gives the x co-ordinates of each hex tile
hxb#ycm #gives the y co-ordinates of each hex tile
hxb#count #gives the cell size for each hex tile
points(x=hxb#xcm, y=hxb#ycm, pch=hxb#count)
You can just feed these three vectors into any plotting tool you normally use.. there is the usual tweaking of size scaling, etc. but it's far better than the stubborn hexplot function. The problem I found with the ggplot2 stat_binhex is that I couldn't get the hexes to be different sizes... just different colors.
if you really want hexagons, plotrix has a hexagon drawing function that i think is fine.