I have a dot plot and I'd like to color the dots so I have a d$color vector that corresponds to the color for a particular dot.
Question 1:
When you run the code below you can see the dots are not colored properly? Do you know how to color them properly? The code needs to dynamically handle the situation where the colors change. For example in this case "red" is the first color but that will not always be the case.
Question 2: Do you also know how to make the dots filled instead of transparent?
library(mosaic)
binwidth <- 1
dat <- c(1, 1, 1, 2, 3, 3, 4, 4, 5, 5)
d <- data.frame(x=dat, color=c("red", "green", "blue", "blue", "purple", "red",
"red", "blue", "green", "green"))
dotPlot(~x, data=d, groups=color,
breaks=seq(min(d$x) - binwidth, max(d$x) + binwidth, binwidth),
cex=1, col=as.factor(d$color))
Question 3: Can you run this code? The soltuion does not seem to work here:
n=50
r =rnorm(n)
dat = sample(r ,n= 1,size = n, replace = TRUE)
d = data.frame( x = dat, color = c(rep("red",n/2), rep("green",n/2)))
dotPlot(d$x, breaks = seq(min(d$x)-.1,max(d$x)+.1,.1)) # this works
dotPlot(d$x, breaks = seq(min(d$x)-.1,max(d$x)+.1,.1), groups = color,col = levels(d$color) ) # this does not work
To colour the points as desired, pass a vector of colours that corresponds to the colours that you want for your groups (so here, a vector of 4 colours, not a vector of 10 colours).
dotPlot(~x, data=d, groups=color, col=levels(d$color),
breaks=seq(min(d$x) - binwidth, max(d$x) + binwidth, binwidth))
To change the symbol, use pch (see ?pch for a list of built-in plotting characters).
dotPlot(~x, data=d, groups=color, col=levels(d$color), pch=20,
breaks=seq(min(d$x) - binwidth, max(d$x) + binwidth, binwidth))
Regarding the Q2, simply changing the type of "point" by default with the argument "pch".
dotPlot(~x, data=d, groups = color, breaks = seq(min(d$x)-binwidth, max(d$x)+binwidth,binwidth), cex = 1, col = d$color, pch = 16)
Related
I am trying to plot in base R with the regular plot() fcn. However, when passing a vector of which pch to use, it will not plot the pch, it will only plot the number '1' instead of the shape of the pch I am calling.
Generating some data (my real data has over 400 rows for both the loads and meta objects:
loads <- data.frame(PC1 = c(11.32, 13.18, 12.82, 24.70), PC2 = c(-23.05, -24.71, -20.28, 10.09))
row.names(loads) <- c("100_A", "100_B", "100_C", "100_Orig")
meta <- data.frame(pch = c(17, 17, 17, 16), color = c("red", "red", "blue", "blue"))
row.names(meta) <- row.names(loads)
To plot:
x <- loads[, 1] ; y <- loads[, 2]
pch <- meta$pch
col <- meta$color
plot(x, y,
col = col, pch = pch, cex = 2, lwd = 4,
xlab = paste("PC1"), ylab = paste("PC2"))
Now, this will graph the correct color (red and blue) in the order I have them in the vector; the real issue becomes the plotting the pch. Instead of a circle (pch = 16) or a triangle (pch = 17) it's plotting a red or blue number 1 instead! I have included a pic of what my data is actually doing.
Thinking that the pch vector I am passing cannot have quotes around it, I have removed the quotes with the following code:
pch <- meta$pch
pch <-as.vector(noquote(pch))
class(pch)
[1] "character"
However, this generates the same results (getting a number 1 plotted). Interestingly, when use this code, it works fine. It turns all my colors to blue, and I get nice blue circles.
plot(x, y,
col = "blue, pch = 16, cex = 2, lwd = 4,
xlab = paste("PC1"), ylab = paste("PC2"))
This tells me that the plot function isn't recognizing my long vector composed of pch 16 and 17's mixed in.
Alternatively, if I use the rep function to generate my pch vector, a test shows it works fine. But I have over 400 rows. I cannot manually type rep for each pch. I will be here for eternity typing that out.
Any suggestions on what to do?????
Try defining the col as character and the pch as numeric like this:
plot(x, y,
col = as.character(col), pch = as.numeric(pch), cex = 2, lwd = 4,
xlab = paste("PC1"), ylab = paste("PC2"))
Looking at this code:
pairs(Iris[1:3], main = "Anderson's Iris Data -- 3 species",
pch = c(21), cex = 2,bg = c("red","green3","blue")[unclass(iris$Species)])
is it possible to show the groups/classes Species as legend color coded?
pairs(iris[1:3], main = "Anderson's Iris Data -- 3 species",
pch = c(21), cex = 2, bg = c("red","green3","blue")[unclass(iris$Species)], oma=c(4,4,6,10))
par(xpd=TRUE)
legend(0.55, 1, as.vector(unique(iris$Species)), fill=c("red", "green3", "blue"))
From ?pairs:
Graphical parameters can be given as arguments to plot such as main. par("oma") will be set appropriately unless specified. Hence any attempts to specify par before pairs will result in override.
Additionally it is very complicated to control the legend position in pairs.
I recommend using library(GGally)
library(GGally)
ggpairs(iris, aes(color = Species), columns = 1:4)
When using glmnet and making a plot of the coefficient path, I would like to remove the axis above the plot.
How do you remove this axis? I found this toy example on the web:
library(glmnet)
age <- c(4,8,7,12,6,9,10,14,7)
gender <- c(1,0,1,1,1,0,1,0,0) ; gender<-as.factor(gender)
bmi_p <- c(0.86,0.45,0.99,0.84,0.85,0.67,0.91,0.29,0.88)
m_edu <- c(0,1,1,2,2,3,2,0,1); m_edu<-as.factor(m_edu)
p_edu <- c(0,2,2,2,2,3,2,0,0); p_edu<-as.factor(p_edu)
f_color <- c("blue", "blue", "yellow", "red", "red", "yellow", "yellow", "red", "yellow")
asthma <- c(1,1,0,1,0,0,0,1,1)
f_color <- as.factor(f_color)
xfactors <- model.matrix(asthma ~ gender + m_edu + p_edu + f_color)[,-1]
x <- as.matrix(data.frame(age, bmi_p, xfactors))
glmmod<-glmnet(x,y=as.factor(asthma),alpha=1,family='binomial')
plot(glmmod,xvar="lambda", axes=FALSE)
This unwanted axis is made with axis function, I guess. We can use this function one more time to cover it. The trick is as follows:
1) Create a sequence with many points at which tick-marks are to be drawn.
2) Make them bigger (lengthen upwards)
3) Enlarge the width of the axis
4) Change the white colour and switch off labels
plot(glmmod, xvar = "lambda", axes = F, xlab = "", ylab = "")
axis(side = 3,
at = seq(par("usr")[1], par("usr")[2], len = 1000),
tck = -0.5,
lwd = 2,
col = "white",
labels = F)
It is easy to change the default strip height for lattice plots: the par.strip.text argument is all that one needs. But is there a simple way to to have strips of different heights within one multi-panel lattice plot?
I have in mind a plot with two rows of panels. The height of the strips in the first row would differ from the height of the strips in the second row.
I think that I can create such a figure by creating two plots –– one for the first row, another for the second row –– and then using grid.layout to position them. But I'd like to know if there is a more straightforward way to create such a figure.
I modified an example from this question (which is a much closer duplicate) and managed to achieve this:
bgColors <- c("black", "green4", "blue", "red", "purple", "yellow")
txtColors <- c("white", "yellow", "white", "white", "green", "red")
stripHt <- rep(c(-1,0),each = 3)
# Create a function to be passes to "strip=" argument of xyplot
myStripStyle <- function(which.panel, factor.levels, ...) {
panel.rect(0, stripHt[which.panel], 1, 1,
col = bgColors[which.panel],
border = 1)
panel.text(x = 0.5, y = 0.5,
font=2,
lab = factor.levels[which.panel],
col = txtColors[which.panel])
}
xyplot(yield ~ year | site, data = barley, strip=myStripStyle)
Ignore the horrible colors. You get the point, we're just using a custom strip function.
I have a 3 column matrix; plots are made by points based on column 1 and column 2 values, but colored based on column 2 (6 different groups). I can successfully plot all points, however, the last plot group (group 6) which was assigned the color purple, masks the plots of the other groups. Is there a way to make the plot points more transparent?
s <- read.table("/.../parse-output.txt", sep="\t")
dim(s)
[1] 67124 3
x <- s[,1]
y <- s[,2]
z <- s[,3]
cols <- cut(z, 6, labels = c("pink", "red", "yellow", "blue", "green", "purple"))
plot(x, y, main= "Fragment recruitment plot - FR-HIT", ylab = "Percent identity", xlab = "Base pair position", col = as.character(cols), pch=16)
Otherwise, you have function alpha in package scales in which you can directly input your vector of colors (even if they are factors as in your example):
library(scales)
cols <- cut(z, 6, labels = c("pink", "red", "yellow", "blue", "green", "purple"))
plot(x, y, main= "Fragment recruitment plot - FR-HIT",
ylab = "Percent identity", xlab = "Base pair position",
col = alpha(cols, 0.4), pch=16)
# For an alpha of 0.4, i. e. an opacity of 40%.
When creating the colors, you may use rgb and set its alpha argument:
plot(1:10, col = rgb(red = 1, green = 0, blue = 0, alpha = 0.5),
pch = 16, cex = 4)
points((1:10) + 0.4, col = rgb(red = 0, green = 0, blue = 1, alpha = 0.5),
pch = 16, cex = 4)
Please see ?rgb for details.
Transparency can be coded in the color argument as well. It is just two more hex numbers coding a transparency between 0 (fully transparent) and 255 (fully visible). I once wrote this function to add transparency to a color vector, maybe it is usefull here?
addTrans <- function(color,trans)
{
# This function adds transparancy to a color.
# Define transparancy with an integer between 0 and 255
# 0 being fully transparant and 255 being fully visable
# Works with either color and trans a vector of equal length,
# or one of the two of length 1.
if (length(color)!=length(trans)&!any(c(length(color),length(trans))==1)) stop("Vector lengths not correct")
if (length(color)==1 & length(trans)>1) color <- rep(color,length(trans))
if (length(trans)==1 & length(color)>1) trans <- rep(trans,length(color))
num2hex <- function(x)
{
hex <- unlist(strsplit("0123456789ABCDEF",split=""))
return(paste(hex[(x-x%%16)/16+1],hex[x%%16+1],sep=""))
}
rgb <- rbind(col2rgb(color),trans)
res <- paste("#",apply(apply(rgb,2,num2hex),2,paste,collapse=""),sep="")
return(res)
}
Some examples:
cols <- sample(c("red","green","pink"),100,TRUE)
# Fully visable:
plot(rnorm(100),rnorm(100),col=cols,pch=16,cex=4)
# Somewhat transparant:
plot(rnorm(100),rnorm(100),col=addTrans(cols,200),pch=16,cex=4)
# Very transparant:
plot(rnorm(100),rnorm(100),col=addTrans(cols,100),pch=16,cex=4)
If you are using the hex codes, you can add two more digits at the end of the code to represent the alpha channel:
E.g. half-transparency red:
plot(1:100, main="Example of Plot With Transparency")
lines(1:100 + sin(1:100*2*pi/(20)), col='#FF000088', lwd=4)
mtext("use `col='#FF000088'` for the lines() function")
If you decide to use ggplot2, you can set transparency of overlapping points using the alpha argument.
e.g.
library(ggplot2)
ggplot(diamonds, aes(carat, price)) + geom_point(alpha = 1/40)