Most efficient way of drawing a heatmap from matrix with OpenGL? - r

Assume a matrix m of integer values:
m <- matrix(sample(1:10, 100, replace = TRUE), nrow = 10)
Given a colour palette that maps those values from 1 to 10 to some colours, how to show matrix m as a heatmap in R with OpenGL graphics, e.g. using the rgl package? (Preferably in the most efficient way.)

The very thorough answer here suggests this may not be what you want; you might want to try the solution below against the other solutions benchmarked there. Nonetheless:
Set up data and colour map
set.seed(101)
library(viridisLite)
vv <- viridis(10)
m <- matrix(sample(1:10, 100, replace = TRUE), nrow = 10)
Draw the picture:
library(rgl)
view3d(theta=0, phi=0) ## head-on view
par3d(zoom=0.7) ## (almost) fill window
surface3d(x = 1:10, y = 1:10, z = matrix(0, 10,10),
color = vv[m],
smooth=FALSE, lit=FALSE ## turn off smoothing/lights
)
You may need to use pop3d() between surfaces to clear the previous surface ...

Related

scatter plot in R of many data 10 or more

hello I must do a multivariate analysis to this data
but I have to make a scatter plot of the data and I don't know that very well
This with the pairs function, if there is any way to do it and make it presentable, thank you very much.
You might give GGally::ggpairs a try. It's relatively automatic:
library(GGally)
data <- as.data.frame(matrix(rnorm(10000),ncol = 10))
data[,2] <- sample(1:6, 1000, replace = TRUE)
data[,3] <- rpois(1000,1)
data[,9] <- as.factor(sample(1:3, 1000, replace = TRUE))
ggpairs(data)

Random Graph Function in R

I have an assignment in which I have to generate my own random graph function in R, with an igraph output. I've figured out that the easiest way to do this is to simply generate a square matrix and then build a function which creates edges between the nodes in the matrix. However I'd like to do something special, where the probability of the edges are based on forming a higher likelihood of sybil networks. Would look like this:
My matrix is generated and visualised quite simply like this:
library(ggraph)
library(igraph)
NCols <- 20
NRows <- 20
myMat <-matrix(runif(NCols*NRows), ncol = NCols)
myMat
randomgraph <- graph_from_adjacency_matrix(myMatG, mode = "undirected", weighted = NULL, diag = TRUE, add.colnames = NULL, add.rownames = NA)
randomgraph %>%
ggraph() +
geom_node_point(colour = "firebrick4", size = 0.5, show.legend = F)
I know there are functions like Erdos-Renyi Random- (for a true random graph), Barabási-Albert Scale-Free- and Watts-Strogatz Small-World graphs. I'm trying to write my own with a unique twist.
Any advice or code snippets on how to write my own preferential attachment function for the random matrix would be greatly appreciated! Thank you!

Raster or RGB data cube plotting with lattice package

Suppose I have this very simple 2x2 RGB datacube that I want to plot:
set.seed(2017)
dc <- array(runif(12), dim = c(2,2,3))
I can plot this just by rasterizing the datacube:
plot(as.raster(dc), interpolate = FALSE)
But I would like to plot this data cube with the lattice package (for uniformity sake since I am mainly using it for other plotting too).
Is this possible? I am looking at levelplot, but am not able to make it work.
The problem you have is that lattice needs a matrix, that is a numeric matrix, and rasters of RGB become a factor matrix:
r <-as.raster(dc)
r
gives this result:
[,1] [,2]
[1,] "#ECC478" "#780AAC"
[2,] "#89C546" "#4A6F01"
to use it as lattice you need to transform this into a numeric matrix, this looks long but it seems is the only way to ensure to keep the order:
m <- matrix(as.numeric(as.factor(as.vector(as.matrix(r)))), ncol= 2)
levelplot(m, panel = panel.levelplot.raster)
The problem you will get here is that you won't keep the same RGB colors, but it's a lattice solution.
Ok, this turned out to be quite an endeavor with levelplot.
I convert the RGB hex color values from raster to integers, and then use these values to map them to the color palette of the raster.
set.seed(2017)
dc <- array(runif(12), dim = c(2,2,3))
plot(as.raster(dc), interpolate = FALSE)
# convert color hexadecimals to integers
rgbInt <- apply(as.raster(dc), MARGIN = c(1,2),
FUN = function(str){strtoi(substring(str, 2), base = 16)})
rgbIntUnq <- unique(as.vector(rgbInt))
lattice::levelplot(x = t(rgbInt), # turn so rows become columns
at = c(0,rgbIntUnq),
col.regions = sprintf("#%06X", rgbIntUnq[order(rgbIntUnq)]), # to hex
ylim = c(nrow(rgbInt) + 0.5, 1 - 0.5), # plot from top to bottom
xlab = '', ylab = '')
The legend can also be removed with colorkey = FALSE property.
I wonder whether there are simpler ways to do the same.

Easiest way to plot inequalities with hatched fill?

Refer to the above plot. I have drawn the equations in excel and then shaded by hand. You can see it is not very neat. You can see there are six zones, each bounded by two or more equations. What is the easiest way to draw inequalities and shade the regions using hatched patterns ?
To build up on #agstudy's answer, here's a quick-and-dirty way to represent inequalities in R:
plot(NA,xlim=c(0,1),ylim=c(0,1), xaxs="i",yaxs="i") # Empty plot
a <- curve(x^2, add = TRUE) # First curve
b <- curve(2*x^2-0.2, add = TRUE) # Second curve
names(a) <- c('xA','yA')
names(b) <- c('xB','yB')
with(as.list(c(b,a)),{
id <- yB<=yA
# b<a area
polygon(x = c(xB[id], rev(xA[id])),
y = c(yB[id], rev(yA[id])),
density=10, angle=0, border=NULL)
# a>b area
polygon(x = c(xB[!id], rev(xA[!id])),
y = c(yB[!id], rev(yA[!id])),
density=10, angle=90, border=NULL)
})
If the area in question is surrounded by more than 2 equations, just add more conditions:
plot(NA,xlim=c(0,1),ylim=c(0,1), xaxs="i",yaxs="i") # Empty plot
a <- curve(x^2, add = TRUE) # First curve
b <- curve(2*x^2-0.2, add = TRUE) # Second curve
d <- curve(0.5*x^2+0.2, add = TRUE) # Third curve
names(a) <- c('xA','yA')
names(b) <- c('xB','yB')
names(d) <- c('xD','yD')
with(as.list(c(a,b,d)),{
# Basically you have three conditions:
# curve a is below curve b, curve b is below curve d and curve d is above curve a
# assign to each curve coordinates the two conditions that concerns it.
idA <- yA<=yD & yA<=yB
idB <- yB>=yA & yB<=yD
idD <- yD<=yB & yD>=yA
polygon(x = c(xB[idB], xD[idD], rev(xA[idA])),
y = c(yB[idB], yD[idD], rev(yA[idA])),
density=10, angle=0, border=NULL)
})
In R, there is only limited support for fill patterns and they can only be
applied to rectangles and polygons.This is and only within the traditional graphics, no ggplot2 or lattice.
It is possible to fill a rectangle or polygon with a set of lines drawn
at a certain angle, with a specific separation between the lines. A density
argument controls the separation between the lines (in terms of lines per inch)
and an angle argument controls the angle of the lines.
here an example from the help:
plot(c(1, 9), 1:2, type = "n")
polygon(1:9, c(2,1,2,1,NA,2,1,2,1),
density = c(10, 20), angle = c(-45, 45))
EDIT
Another option is to use alpha blending to differentiate between regions. Here using #plannapus example and gridBase package to superpose polygons, you can do something like this :
library(gridBase)
vps <- baseViewports()
pushViewport(vps$figure,vps$plot)
with(as.list(c(a,b,d)),{
grid.polygon(x = xA, y = yA,gp =gpar(fill='red',lty=1,alpha=0.2))
grid.polygon(x = xB, y = yB,gp =gpar(fill='green',lty=2,alpha=0.2))
grid.polygon(x = xD, y = yD,gp =gpar(fill='blue',lty=3,alpha=0.2))
}
)
upViewport(2)
There are several submissions on the MATLAB Central File Exchange that will produce hatched plots in various ways for you.
I think a tool that will come handy for you here is gnuplot.
Take a look at the following demos:
feelbetween
statistics
some tricks

Making a 3D surface from time series data in R

I have a large data set which I would like to make a 3D surface from. I would like the x-axis to be the date, the y-axis to be the time (24h) and the z-axis (height) to be a value I have ($). I am a beginner with R, so the simpler the better!
http://www.quantmod.com/examples/chartSeries3d/ has a nice example, but the code is way to complicated for my skill level!
Any help would be much appreciated - anything I have researched so far needs to have the data sorted, which is not suitable I think.
Several options present themselves, persp() and wireframe(), the latter in package lattice.
First some dummy data:
set.seed(3)
dat <- data.frame(Dates = rep(seq(Sys.Date(), Sys.Date() + 9, by = 1),
each = 24),
Times = rep(0:23, times = 10),
Value = rep(c(0:12,11:1), times = 10) + rnorm(240))
persp() needs the data as the x and y grid locations and a matrix z of observations.
new.dates <- with(dat, sort(unique(Dates)))
new.times <- with(dat, sort(unique(Times)))
new.values <- with(dat, matrix(Value, nrow = 10, ncol = 24, byrow = TRUE))
and can be plotted using:
persp(new.dates, new.times, new.values, ticktype = "detailed", r = 10,
theta = 35, scale = FALSE)
The facets can be coloured using the col argument. You could do a lot worse than study the code for chartSeries3d0() at the page you linked to. Most of the code is just drawing proper axes as neither persp() nor wireframe() handle Date objects easily.
As for wireframe(), we
require(lattice)
wireframe(Value ~ as.numeric(Dates) + Times, data = dat, drape = TRUE)
You'll need to do a bit or work to sort out the axis labelling as wireframe() doesn't work with objects of class "Date" at the moment (hence the cast as numeric).

Resources