R Plotly - Scatter plot: Colouring individual points - r

I am trying to specify the color of the points in my scatter plot. I would like to be able to specify a different color and alpha for each point.
The following snippet gives me the error "Error in grDevices::col2rgb(colors, alpha = alpha) :
invalid color name 'rgba(105,100,30,.6)'"
I am quite stuck on this, any help is appreciated.
Thanks!
library(plotly)
library(ggplot2)
library(igraph)
tree <- make_tree(127,2)
tree_layout <- layout_as_tree(tree)
tree_layout_df <- as.data.frame(tree_layout)
Xn <- tree_layout_df[,1]
Yn <- tree_layout_df[,2]
marker_color <- rep('rgba(105,100,30,.6)',127)
reg_tree_plot <- plot_ly() %>%
add_trace(x=~Xn, y=~Yn, type='scatter', mode='markers',color=~Xn,
colors=marker_color)

Following definition of marker_color is accepted in grDevices. I used runif and replicate to generate 127 (hopefully) different colours.
marker_color <- replicate(127, rgb(runif(1,0,1),runif(1,0,1),runif(1,0,1),runif(1,0,1)) )

Related

Is there a way to create a kissing people curve using ggplot2 in R

Is it possible to create custom graphs using ggplot2, for example I want to create a graph of kissing people.
Simple variant
Not completely, but partially, I was able to reproduce it, everything except for the "lines of the eyes" is not clear how to mark them
But how to make a more complex graph of kissing people. In general, is it possible to somehow approximate such a curve, more voluminou?
thank you for your help.
perhaps not what you are looking for, but if you have already got the image, and want to reproduce it in ggplot, then you can use the following method:
library(tidyverse)
library(magick)
library(terra)
# read image
im <- image_read("./data/kiss_1.png")
# conver to black/white image
im2 <- im %>%
image_quantize(
max = 2,
colorspace = "gray" )
# get a matrix of the pixel-colors
m <- as.raster(im2) %>% as.matrix()
# extract coordinates of the black pixels
df <- as.data.frame(which(m == "#000000ff", arr.ind=TRUE))
df$row <- df$row * -1
# plot point
ggplot(df, aes(x = col, y = row)) + geom_point()

Lines in ggplot order

From library mgcv
i get the points to plot with:
fsb <- fs.boundary(r0=0.1, r=1.1, l=2173)
if with standard graphic package i plot fsb and then i add lines i get :
x11()
plot(fsb)
lines(fsb$x,fsb$y)
I try now with ggplot (this is the line within a bigger code) :
tpdf <- data.frame(ts=fsb$x,ps=fsb$y)
ts=fsb$x
ps=fsb$y
geom_line(data=tpdf, aes(ts,ps), inherit.aes = FALSE)
i get a messy plot:
I think that i'm failing the order in geom_line
This can be solved by using geom_path:
ggplot(tpdf)+
geom_point(aes(ts,ps)) +
geom_path(aes(ts,ps))
You have a very odd way of using ggplot I recommend you to reexamine it.
data:
library(mgcv)
fsb <- fs.boundary(r0 = 0.1, r=2, l=13)
tpdf <- data.frame(ts=fsb$x,ps=fsb$y)
You'll have to specify the group parameter - for example, this
ggplot(tpdf) +
geom_point(aes(ts, ps)) +
geom_line(aes(ts, ps, group = gl(4, 40)))
gives me a plot similar to the one in base R.

Create histogram of raster in R

I want to create a value distribution chart, like a histogram or graph, of a raster image using:
library(raster)
library(sp)
library(rgdal)
DEM <- raster("NR.tif")
hist(DEM)
plot(DEM)
plot() is used to validate my data and shows me an all green image. Supposedly band 1 of 3.
However I can't see other bands?
Obviously the distribution in the histogram doesn't represent interpolated values in the imagefile.
A histogram created in ARCgis is herehist, which I believe represent the true values.
Any suggestions on how to create a histogram of the real values like the image.
Best,
Mathias
You could try
download.file("https://www.dropbox.com/s/t279m5ojners7fl/NR.tif?dl=1",
tf <- tempfile(fileext = ".tif"), mode="wb")
library(raster)
library(tiff)
library(ggplot2)
library(reshape2)
DEM <- readTIFF(tf)
plot(as.raster(DEM))
ggplot(melt(DEM),
aes(value, fill=as.factor(Var3))) +
geom_histogram(position="dodge")
Or, with regards to your update
r <- as.raster(DEM)
tab <- as.data.frame(sort(table(r)))
ggplot(subset(tab, !r %in% c("#F0F0F0", "#000000")),
aes(x=r, y=Freq, fill=I(r))) +
geom_bar(stat="identity") +
theme(axis.text.x = element_text(angle=90))
Try setting the NAvalue to the background color and then call the hist() function or use the ggplot commands from lukeA:
library(raster)
ras <- stack("Downloads/NR.tif")
NAvalue(ras) <- 240
hist(ras)
This results in the following plots:

plot raster with discrete colors using rasterVis

I have a few rasters I would like to plot using gplot in the rasterVis package. I just discovered gplot (which is fantastic and so much faster than doing data.frame(rasterToPoints(r))). However, I can't get a discrete image to show. Normally if r is a raster, I'd do:
rdf=data.frame(rasterToPoints(r))
rdf$cuts=cut(rdf$value,breaks=seq(0,max(rdf$value),length.out=5))
ggplot(rdf)+geom_raster(aes(x,y,fill=cuts))
But is there a way to avoid the call to rasterToPoints? It is very slow with large rasters. I did find I could do:
cuts=cut_interval(r#data#values,n=5)
but if you set the fill to cuts it plots the integer representation of the factors.
Here is some reproducible data:
x=seq(-107,-106,.1)
y=seq(33,34,.1)
coords=expand.grid(x,y)
rdf=data.frame(coords,depth=runif(nrow(coords),0,2)))
names(rdf)=c('x','y','value')
r=rasterFromXYZ(rdf)
Thanks
gplot is a very simple wrapper around ggplot so don't expect too
much from it. Instead, you can use part of its code to build your own
solution. The main point here is to use sampleRegular to reduce the
number of points to be displayed.
library(raster)
library(ggplot2)
x <- sampleRegular(r, size=5000, asRaster = TRUE)
dat <- as.data.frame(r, xy=TRUE)
dat$cuts <- cut(dat$value,
breaks=seq(0, max(dat$value), length.out=5))
ggplot(aes(x = x, y = y), data = dat) +
geom_raster(aes(x, y, fill=cuts))
However, if you are open to plot without ggplot2 you may find useful
this other
answer.

How to plot a violin scatter boxplot (in R)?

I just came by the following plot:
And wondered how can it be done in R? (or other softwares)
Update 10.03.11: Thank you everyone who participated in answering this question - you gave wonderful solutions! I've compiled all the solution presented here (as well as some others I've came by online) in a post on my blog.
Make.Funny.Plot does more or less what I think it should do. To be adapted according to your own needs, and might be optimized a bit, but this should be a nice start.
Make.Funny.Plot <- function(x){
unique.vals <- length(unique(x))
N <- length(x)
N.val <- min(N/20,unique.vals)
if(unique.vals>N.val){
x <- ave(x,cut(x,N.val),FUN=min)
x <- signif(x,4)
}
# construct the outline of the plot
outline <- as.vector(table(x))
outline <- outline/max(outline)
# determine some correction to make the V shape,
# based on the range
y.corr <- diff(range(x))*0.05
# Get the unique values
yval <- sort(unique(x))
plot(c(-1,1),c(min(yval),max(yval)),
type="n",xaxt="n",xlab="")
for(i in 1:length(yval)){
n <- sum(x==yval[i])
x.plot <- seq(-outline[i],outline[i],length=n)
y.plot <- yval[i]+abs(x.plot)*y.corr
points(x.plot,y.plot,pch=19,cex=0.5)
}
}
N <- 500
x <- rpois(N,4)+abs(rnorm(N))
Make.Funny.Plot(x)
EDIT : corrected so it always works.
I recently came upon the beeswarm package, that bears some similarity.
The bee swarm plot is a
one-dimensional scatter plot like
"stripchart", but with closely-packed,
non-overlapping points.
Here's an example:
library(beeswarm)
beeswarm(time_survival ~ event_survival, data = breast,
method = 'smile',
pch = 16, pwcol = as.numeric(ER),
xlab = '', ylab = 'Follow-up time (months)',
labels = c('Censored', 'Metastasis'))
legend('topright', legend = levels(breast$ER),
title = 'ER', pch = 16, col = 1:2)
(source: eklund at www.cbs.dtu.dk)
I have come up with the code similar to Joris, still I think this is more than a stem plot; here I mean that they y value in each series is a absolute value of a distance to the in-bin mean, and x value is more about whether the value is lower or higher than mean.
Example code (sometimes throws warnings but works):
px<-function(x,N=40,...){
x<-sort(x);
#Cutting in bins
cut(x,N)->p;
#Calculate the means over bins
sapply(levels(p),function(i) mean(x[p==i]))->meansl;
means<-meansl[p];
#Calculate the mins over bins
sapply(levels(p),function(i) min(x[p==i]))->minl;
mins<-minl[p];
#Each dot is one value.
#X is an order of a value inside bin, moved so that the values lower than bin mean go below 0
X<-rep(0,length(x));
for(e in levels(p)) X[p==e]<-(1:sum(p==e))-1-sum((x-means)[p==e]<0);
#Y is a bin minum + absolute value of a difference between value and its bin mean
plot(X,mins+abs(x-means),pch=19,cex=0.5,...);
}
Try the vioplot package:
library(vioplot)
vioplot(rnorm(100))
(with awful default color ;-)
There is also wvioplot() in the wvioplot package, for weighted violin plot, and beanplot, which combines violin and rug plots. They are also available through the lattice package, see ?panel.violin.
Since this hasn't been mentioned yet, there is also ggbeeswarm as a relatively new R package based on ggplot2.
Which adds another geom to ggplot to be used instead of geom_jitter or the like.
In particular geom_quasirandom (see second example below) produces really good results and I have in fact adapted it as default plot.
Noteworthy is also the package vipor (VIolin POints in R) which produces plots using the standard R graphics and is in fact also used by ggbeeswarm behind the scenes.
set.seed(12345)
install.packages('ggbeeswarm')
library(ggplot2)
library(ggbeeswarm)
ggplot(iris,aes(Species, Sepal.Length)) + geom_beeswarm()
ggplot(iris,aes(Species, Sepal.Length)) + geom_quasirandom()
#compare to jitter
ggplot(iris,aes(Species, Sepal.Length)) + geom_jitter()

Resources