R: color certain cells in Matrix - r

I am wondering whether I can color only certain cells in an R matrix using the
image
command. Currently, I am doing this:
library(Matrix)
args <- commandArgs(trailingOnly=TRUE)
csv_name <- args[1]
pdf_name <- args[2]
pdf(pdf_name)
data <- scan(csv_name, sep=",")
len <- length(data)
num <- sqrt(len)
matrix <- Matrix(data, nrow=num, ncol=num)
image(matrix)
dev.off()
The CSV file contains values between 0 and 1.
Executing the above code gives me the following image:
Now, I want to color in each row the six smallest values red.
Does anyone have an idea how to achieve this?
Thanks in advance,
Sven

Matrix seems to use lattice (levelplot). You can add a layer on top,
m = Matrix(1:9, 3)
library(latticeExtra)
image(m) + layer(panel.levelplot(1:2,1:2,1:2,1:2, col.regions="red"))
Edit: actually, it makes more sense to give the colors in the first place,
levelplot(as.matrix(m), col.regions=c(rep("red", 6), "blue", "green", "yellow"), at=1:9)
but I haven't succeeded with image:
image(m, col.regions = c(rep("red", 6), "blue", "green", "yellow"), at=1:9)
I may have missed a fine point in the docs...

You can also simply make another matrix where all values are NaN and then add a value of 1 to those that you want to highlight:
set.seed(1)
z <- matrix(rnorm(100), 10,10)
image(z)
z2 <- z*NaN
z2[order(z)[1:5]] <- 1
image(z2, add=TRUE, col=4)

Related

plot all rows of matrix in the same plot in R

I want to create a plot.
x values are matt 's colnames : count.4, count.5, ...
y values are range of matt elements
the scatter POINTS on plot are corresponding matt[i,j] elemnts, such that points for each row have the same color.
for (rr in 2:8) {
rownames(matt)[rr-1] <- paste('class', rr, sep='.')
for(cc in 4:20) {
matt[rr-1, cc-3] <- rr * cc
colnames(matt)[cc-3] <- paste('count', cc, sep='.')
}
}
I am really stuck at how to get such plot. Any help or hint is very appreciated. I found
matplot (c(4:20), cbind(matt[1,]:mat[7,]), pch = 19, ylim = range(c(matt[1,]:mat[7,]))
I see cbind(matt[1,]:matt[7,]) is not of correct format. but I do not know how to write this such than for a matrix with many more rows I do not have to write all matt[j,]
how can I get to this?
Edit. this is the plot I get when I use cbind(matt[1,],matt[2,],...,matt[7,])
Other than the efficient way coding this, I do not know why there are two sets of black points. can I label colors to corresponding "class" so that the plot gets easier to be read.
Normally series are stored in columns, not in rows, but if they are in rows just use transpose. There are other color palettes available at ?rainbow and a long vector of colors available via colors() if you don't like the colors we used here. (We used the input in the Note at the end.)
col <- rainbow(length(rr))
matplot(cc, t(mat), pch = 19, col = col, type = "o")
legend("topleft", legend = rownames(mat), pch = 19, col = col, lty = 1)
Note
rr <- 2:8
cc <- 4:20
mat <- outer(rr, cc)
dimnames(mat) <- list(paste0("class.", rr), paste0("count.", cc))

Dynamically coloring boxplot in R

I have data with the following columns: lot, sublot, size, data. I have multiple lot(s) and each lot can have multiple sublot(s). Each sublot has size(s) of 1 to 4.
I have created a boxplot for this data using the following code:
df <-
readXL("Z:/R_Files/example.xlsx",
rownames=FALSE, header=TRUE, na="", sheet="Sheet1",
stringsAsFactors=TRUE)
x11()
par(mar=c(10.1, 5.1, 4.1, 2.1))
boxplot(data ~ size*sublot*lot,
xlab="", ylab="Data", main="Data by Size, Sublot, Lot",
las=2,
data=df)
title(xlab='Size.Sublot.Lot', line=9)
I wanted to use the boxfill command to color each boxplot based on the lot#. I have seen two solutions:
create a vector and explicitly specify the colors to be used e.g. colr = c("red", "red", "red", .... "green", "green", "green", ... "blue"). The problem with this solution is that it requires me to know apriori the number of lots in df and number of times the color needs to be repeated.
use "ifelse" statement. The problem with this solution is that (a) I need to know the number of lots and (b) I need to create multiple nested ifelse statements.
I would prefer to create a "dynamic" solution which creates the color vector based on the number of lot entries I have in my file.
I have tried to create:
uniqlot <- unique(df$lot)
colr <- palette(rainbow(length(uniqlot)))
but am stuck since the entries in the colr vector do not repeat for the number of unique combinations of size.sublot.lot. Note: I want all boxplots for lot ABC to be colored with one color, all boxplots for lot DEF to be colored with another color etc.
I am attaching a picture of the uncolored boxplot. Uncolored Boxplot
Raw data (example.xlsx) can be accessed at the following link:
example.xlsx
This is what I would do:
n1 <- length(unique(df$sublot))
n2 <- length(unique(df$size))
colr <- palette(rainbow(length(n)))
colr <- rep(colr, each = n1*n2)
boxplot(data ~ size*sublot*lot,
col = colr,
xlab="", ylab="Data", main="Data by Size, Sublot, Lot",
las=2,
data=df)
Using ggplot:
df$size <- as.factor(df$size)
ggplot(df, aes(sublot, data, group = interaction(size, sublot), col = size)) +
geom_boxplot() +
facet_wrap(~lot, nrow = 1)
Also, you can get rid of df$size <- as.factor(df$size) if you want continuous colour.
thanks to the pointers provided in the responses and after digging around a little more, I was able to find a solution to my own question. I wanted to submit this piece of code in case someone needed to replicate.
Here is a picture of the boxplot this code creates (and I wanted to create). colored boxplot
df <-
readXL("Z:/R_Files/example.xlsx",
rownames=FALSE, header=TRUE, na="", sheet="Sheet1",
stringsAsFactors=TRUE)
unqlot <- unique(df$lot)
unqsublot <- unique(df$sublot)
unqsize <- unique(df$size)
cul <- palette(rainbow(length(unqlot)))
culur <- character()
for (i in 1:length(unqsize)) {
culur_temp = rep(cul[i], each=(length(unqsize)*length(unqsublot)))
culur = c(culur, culur_temp)
}
par(mar=c(10.1, 5.1, 4.1, 2.1))
boxplot(data ~ size*sublot*lot,
xlab="", ylab="Data", main="Data by Size, Sublot, Lot",
col = culur,
las=2,
data=df)

colorRamp returns 0

I'm trying to plot lines and color the lines based on the probability of that connection. Given a vector of probabilities, I use:
colfunc <- colorRamp(c("white", "red"))
colors <- colfunc(probs)
colors is then an nx3 matrix of rgb values. However, colfunc quite often returns a 0 value, so when i attempt to plot using these colors, R complains
Error in col2rgb(colors) : numerical color values must be positive
Is there an error in the way I am defining my color function?
Your function works fine, I think, but it doesn't return colors you can use with plot, because plot wants a color, not RGB values in a matrix.
There's probably a better way, but you can simply covert the matrix:
probs <- runif(10)
colors <- colfunc(probs)
my_col = apply(colors, MARGIN = 1, function(x) rgb(x[1]/255, x[2]/255, x[3]/255))
plot(1:10, 1:10, col = my_col) # should work fine
or you could just wrap your function
better_colfunc <- function(x, ramp = colorRamp(c("white", "red"))) {
colors <- ramp(x)
colors = apply(colors, MARGIN = 1, function(x) rgb(x[1]/255, x[2]/255, x[3]/255))
return(colors)
}
plot(1:10, 1:10, col = better_colfunc(probs, ramp = colfunc))
As for "colfunc quite often returns a 0 value", and other issues, you'll need to share both some data (what do your probs look like?) as well as perhaps the actual plotting code. See here for tips on making reproducible questions.
I am a bit confused what you are trying to do...the col2rgb function returns rgb values, so if you already have those then what do you want?
Or if you want rgb, why not use:
col2rgb(c("white", "red"))

Heatmap like plot with Lattice

I can not figure out how the lattice levelplot works. I have played with this now for some time, but could not find reasonable solution.
Sample data:
Data <- data.frame(x=seq(0,20,1),y=runif(21,0,1))
Data.mat <- data.matrix(Data)
Plot with levelplot:
rgb.palette <- colorRampPalette(c("darkgreen","yellow", "red"), space = "rgb")
levelplot(Data.mat, main="", xlab="Time", ylab="", col.regions=rgb.palette(100),
cuts=100, at=seq(0,1,0.1), ylim=c(0,2), scales=list(y=list(at=NULL)))
This is the outcome:
Since, I do not understand how this levelplot really works, I can not make it work. What I would like to have is the colour strips to fill the whole window of the corresponding x (Time).
Alternative solution with other method.
Basically, I'm trying here to plot the increasing risk over time, where the red is the highest risk = 1. I would like to visualize the sequence of possible increase or clustering risk over time.
From ?levelplot we're told that if the first argument is a matrix then "'x' provides the
'z' vector described above, while its rows and columns are
interpreted as the 'x' and 'y' vectors respectively.", so
> m = Data.mat[, 2, drop=FALSE]
> dim(m)
[1] 21 1
> levelplot(m)
plots a levelplot with 21 columns and 1 row, where the levels are determined by the values in m. The formula interface might look like
> df <- data.frame(x=1, y=1:21, z=runif(21))
> levelplot(z ~ y + x, df)
(these approaches do not quite result in the same image).
Unfortunately I don't know much about lattice, but I noted your "Alternative solution with other method", so may I suggest another possibility:
library(plotrix)
color2D.matplot(t(Data[ , 2]), show.legend = TRUE, extremes = c("yellow", "red"))
Heaps of things to do to make it prettier. Still, a start. Of course it is important to consider the breaks in your time variable. In this very simple attempt, regular intervals are implicitly assumed, which happens to be the case in your example.
Update
Following the advice in the 'Details' section in ?color2D.matplot: "The user will have to adjust the plot device dimensions to get regular squares or hexagons, especially when the matrix is not square". Well, well, quite ugly solution.
par(mar = c(5.1, 4.1, 0, 2.1))
windows(width = 10, height = 2.5)
color2D.matplot(t(Data[ , 2]),
show.legend = TRUE,
axes = TRUE,
xlab = "",
ylab = "",
extremes = c("yellow", "red"))

How do I highlight an observation's bin in a histogram in R

I want to create a histogram from a number of observations (i.e. d <- c(1,2.1,3.4,4.5) ) and then highlight the bin that a particular observation falls in, such that I have an output that looks like this:
how do I do this in R?
Expanding on dangerstat's answer, here is a little function that will automatically find which bin contains the value that you want to highlight:
highlight <- function(x, value, col.value, col=NA, ...){
hst <- hist(x, ...)
idx <- findInterval(value, hst$breaks)
cols <- rep(col, length(hst$counts))
cols[idx] <- col.value
hist(x, col=cols, ...)
}
Now
x <- rnorm(100)
highlight(x, 1.2, "red")
will highlight the bin with 1.2 in it in red.
x = rnorm(100)
hist(x,br=10,col=c(rep(0,9),1))
Clearly this will color the last column so tweak the col= bit for your needs
Thanks
dangerstat

Resources