I have a code similar to this:
x <- rnorm(100)
y <- density(x, n = 1000)
plot(y)
polygon(y,col="red")
However, I would also like to add a colour gradient to a density plot in basic R, particularly using a palette such as the Spectral from blue to red. In this way, the output would look like this:
I appreciate any help! Thanks!
You could use segments() to add countless line segments with gradient colours.
x <- rnorm(100)
dens <- density(x, n = 1000)
plot(dens)
segments(dens$x, 0, dens$x, dens$y, col = hcl.colors(1000, "Spectral", rev = TRUE))
polygon(dens)
Related
In the above image the surface colored in z axis (like heat map). I am using plot3d()
plot3d(data$x, data$y, data$z, name = 'Plotly3D graph', type = 'l', axes=F)
I have to repeat the same color as of in the image. By using above code I can get the 3D square but I dont know where to set the color of z axis as same as the image. Please help me in plot3D. If full code is needed will post if required.
Here is sample code:
data1 <- read.csv(file.choose(),1)
# retrieve age column from csv file
var1 <- data1$age
z1 <- rep(1, times=length(var1))
plot3d(var1, length(var1), z1, type="l", xaxt='n', yaxt='n', xlab="Jitter in
ns", ylab="Counts", size=0.05,expand=0.75, col=color[zcol],
ticktype="detailed", zlab="")
Here's one version, using a function from one of the answers to How do I generate a mapping from numbers to colors in R?.
# A function based on Dave X's answer to the colour mapping question
map2color <- function(x, pal, limits = range(x)){
pal[findInterval(x, seq(limits[1], limits[2], length.out = length(pal) + 1),
all.inside=TRUE)]
}
persp3d(volcano, col = map2color(volcano, rainbow(100)))
This produces this image:
To produce solid edges ("curtains" in plot3D), just surround the data with extra rows and columns of its minimum value. For example,
m <- min(volcano)
volcano2 <- cbind(m, rbind(m, volcano, m), m)
To make the edges look flat, you need to add x and y values, just a tiny bit outside the original ones:
x <- c(0.9999, 1:nrow(volcano), nrow(volcano) + 0.0001)
y <- c(0.9999, 1:ncol(volcano), ncol(volcano) + 0.0001)
persp3d(x, y, volcano2, col = map2color(volcano2, heat.colors(100)))
I switched the palette to heat.colors just for some variety.
I'm producing an elevation map with R base function "image". Nonetheless, I'd like to get a smoother transition between levels so the image looks less pixelated. The logical solution is adding a wider color palette, which I already did, but the result isn't satisfactory yet. How can I achieve a nice smoothing effect without altering the coordinate system (I need it to overlay a series of segments and points)?
x <- 10*(1:nrow(volcano))
y <- 10*(1:ncol(volcano))
shades = colorRampPalette(c("yellow", "red"))
image(x, y, volcano,
col=shades(100),breaks=seq(min(volcano),max(volcano),
(max(volcano)- min(volcano))/100),axes = FALSE)
segments(x0=c(100,600), x1=c(600,100),
y0=c(100,600),
y1=c(600,100))
points(x=seq(100,800,100), y=rep(300,8),pch=16,col="blue",cex=3)
axis(1, at = seq(100, 800, by = 100))
axis(2, at = seq(100, 600, by = 100))
For some reason interpolate=FALSE is hard-coded in image.default, but you can use the lower-level rasterImage function directly:
m <- cut(scales::rescale(volcano), 100)
levels(m) <- shades(100)
m <- as.character(m)
dim(m) <- dim(volcano)
m <- t(m)[ncol(m):1,]
rasterImage(as.raster(m), min(x), min(y), max(x), max(y), interpolate = TRUE)
Side-by-side comparison:
I want to plot a matrix of z values with x rows and y columns as a surface similar to this graph from MATLAB.
Surface plot:
Code to generate matrix:
# Parameters
shape<-1.849241
scale<-38.87986
x<-seq(from = -241.440, to = 241.440, by = 0.240)# 2013 length
y<-seq(from = -241.440, to = 241.440, by = 0.240)
matrix_fun<-matrix(data = 0, nrow = length(x), ncol = length(y))
# Generate two dimensional travel distance probability density function
for (i in 1:length(x)) {
for (j in 1:length(y)){
dxy<-sqrt(x[i]^2+y[j]^2)
prob<-1/(scale^(shape)*gamma(shape))*dxy^(shape-1)*exp(-(dxy/scale))
matrix_fun[i,j]<-prob
}}
# Rescale 2-d pdf to sum to 1
a<-sum(matrix_fun)
matrix_scale<-matrix_fun/a
I am able to generate surface plots using a couple methods (persp(), persp3d(), surface3d()) but the colors aren't displaying the z values (the probabilities held within the matrix). The z values only seem to display as heights not as differentiated colors as in the MATLAB figure.
Example of graph code and graphs:
library(rgl)
persp3d(x=x, y=y, z=matrix_scale, color=rainbow(25, start=min(matrix_scale), end=max(matrix_scale)))
surface3d(x=x, y=y, z=matrix_scale, color=rainbow(25, start=min(matrix_scale), end=max(matrix_scale)))
persp(x=x, y=y, z=matrix_scale, theta=30, phi=30, col=rainbow(25, start=min(matrix_scale), end=max(matrix_scale)), border=NA)
Image of the last graph
Any other tips to recreate the image in R would be most appreciated (i.e. legend bar, axis tick marks, etc.)
So here's a ggplot solution which seems to come a little bit closer to the MATLAB plot
# Parameters
shape<-1.849241
scale<-38.87986
x<-seq(from = -241.440, to = 241.440, by = 2.40)
y<-seq(from = -241.440, to = 241.440, by = 2.40)
df <- expand.grid(x=x,y=y)
df$dxy <- with(df,sqrt(x^2+y^2))
df$prob <- dgamma(df$dxy,shape=shape,scale=scale)
df$prob <- df$prob/sum(df$prob)
library(ggplot2)
library(colorRamps) # for matlab.like(...)
library(scales) # for labels=scientific
ggplot(df, aes(x,y))+
geom_tile(aes(fill=prob))+
scale_fill_gradientn(colours=matlab.like(10), labels=scientific)
BTW: You can generate your data frame of probabilities much more efficiently using the built-in dgamma(...) function, rather than calculating it yourself.
In line with alexis_laz's comment, here is an example using filled.contour. You might want to increase your by to 2.40 since the finer granularity increases the time it takes to generate the plot by a lot but doesn't improve quality.
filled.contour(x = x, y = y, z = matrix_scale, color = terrain.colors)
# terrain.colors is in the base grDevices package
If you want something closer to your color scheme above, you can fiddle with the rainbow function:
filled.contour(x = x, y = y, z = matrix_scale,
color = (function(n, ...) rep(rev(rainbow(n/2, ...)[1:9]), each = 3)))
Finer granularity:
filled.contour(x = x, y = y, z = matrix_scale, nlevels = 150,
color = (function(n, ...)
rev(rep(rainbow(50, start = 0, end = 0.75, ...), each = 3))[5:150]))
I am plotting scatter plot for high density of dots.I used Hexbin package and I successfully plot the data.The colour is not pretty,and I am asked to follow a standard colour. I wonder if it is supported by R. Image shows my out put(right) and the wanted colour(left).
Example:
x <- rnorm(1000)
y <- rnorm(1000)
bin<-hexbin(x,y, xbins=50)
plot(bin, main="Hexagonal Binning")
Using the example on the package helpapge for hexbin you can get close using rainbow and playing with the colcuts argument like so...
x <- rnorm(10000)
y <- rnorm(10000)
(bin <- hexbin(x, y))
plot(hexbin(x, y + x*(x+1)/4),main = "Example" ,
colorcut = seq(0,1,length.out=64),
colramp = function(n) rev(rainbow(64)),
legend = 0 )
You will need to play with the legend specification etc to get exactly what you want.
Alternative colour palette suggested by #Roland
## nicer colour palette
cols <- colorRampPalette(c("darkorchid4","darkblue","green","yellow", "red") )
plot(hexbin(x, y + x*(x+1)/4), main = "Example" ,
colorcut = seq(0,1,length.out=24),
colramp = function(n) cols(24) ,
legend = 0 )
I'm a beginner in R and needs a bit of help for my scripting.
I managed to generate scale color gradient using library(ggplot2) on my 2D plots as follows;
z <- c(data$conf)
d <- qplot(x, y, xlab="Dimension 1", ylab="Dimension 2", colour=z)
d
d + scale_colour_gradient(limits=c(0, 1), data=data$conf, low="blue", high="red"))
I'm now trying to reproduce this gradient on a 3D plot, I used scatterplot3d or plot3d. I believe the colorRampPalette create a color gradient based on 327 rows (1…327) while I'm interested in a gradient that is function of values in data$conf. I need a connection, but where?
attach(data)
t1 <- c(data$conf)
jet.colors <- colorRampPalette(c("blue", "red"))
e <- plot3d(x, y, z, col=jet.colors(327))
If you can help me that will be great – Or if you know any 3D plot/scale gradient package that can do a better job, cool too.
You are on the right track with colorRampPalette(), but really need something more like colorRamp(), which 'returns a function that maps values between 0 and 1'.
Even better would be a function -- call it myColorRamp() -- which is like colorRamp() but instead: (a) maps values between min(values) and max(values); and (b) returns the colors as 7-character sRGB strings (e.g. "#F60008"), a format that plot3d() understands.
library(rgl)
myColorRamp <- function(colors, values) {
v <- (values - min(values))/diff(range(values))
x <- colorRamp(colors)(v)
rgb(x[,1], x[,2], x[,3], maxColorValue = 255)
}
x <- sin((1:100)/10)
y <- cos((1:100)/10)
z <- seq(-20, 20, length.out=100)
cols <- myColorRamp(c("red", "blue"), z)
plot3d(x = x, y = y, z = z, col = cols)