I needed help knowing how to associate colors with values.
For example, I have a vector for colors and values as follows i.e.
cols <- c("red", "gray60")
and
numEra <- c(values)
numEra
[1] 1 1 1 2 2 2
How do I associate these values with the colors "red" and "gray60" ??
Maybe you want to use cut like this:
cols <- c("red", "gray60")
numEra <- c(1, 1, 1, 2, 2, 2)
cols[cut(numEra, 2)]
#> [1] "red" "red" "red" "gray60" "gray60" "gray60"
Created on 2022-10-01 with reprex v2.0.2
So each number is now associated with a color.
Related
I am using the R programming language. Using the famous Iris dataset, I created the following plot:
require(MASS)
cols = c('red', 'green', 'blue')
parcoord(iris[ ,-5], col = cols[iris$Species])
From here, I tried to add a legend:
legend("topright", c("setosa", "versicolor", "virginica"), lwd = 2, col = iris$Species, bty = "n")
How can I ensure that the legend colors actually match the colors on the graph? Does R automatically do this?
Thanks
iris$Species is a factor with 3 (integer) levels and associated names:
require(MASS)
str(iris$Species)
#> Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
Thus, using cols[iris$Species] assigns colors based on the factor level, with setosa being the first (red), etc..
You could relevel the factor, which would affect the association of the colors with the species and change the colors (setosa would be 2, hence green), to demonstrate this effect:
iris$Species <- relevel(iris$Species, "versicolor")
str(iris$Species)
#> Factor w/ 3 levels "versicolor","setosa",..: 2 2 2 2 2 2 2 2 2 2 ...
The legend only shows the 3 names and colors, so you could use the factor levels and associated names to make sure they match. Since we changed the order here, this is what we get:
require(MASS)
cols = c('red', 'green', 'blue')
iris$Species <- relevel(iris$Species, "versicolor")
parcoord(iris[ ,-5], col = cols[iris$Species])
legend("top", levels(iris$Species), lwd = 2, col = cols, bty = "n")
Created on 2021-01-22 by the reprex package (v0.3.0)
Here, the Species column of iris is a factor (try running class(iris$Species)). If you then run levels(iris$Species), you will see that the order of the levels is setosa versicolor virginica.
If you convert this factor to an integer value (try as.integer(iris$Species)), you will see that setosa = 1, versicolor = 2, and virginica = 3. When you pass cols[iris$Species] as an argument to parcoord(), you are using this factor as an index, and R silently converts it to an integer vector. Hence, setosa will map to the first element of cols, namely 'red', and so on.
Please see below:
require(MASS)
cols = c('red', 'green', 'blue')
parcoord(iris[ ,-5], col = cols[iris$Species])
legend("topright", levels(iris$Species), lwd = 2, col = cols, inset = 0.05)
This will produce the following plot:
While base R graphics may be sufficient for your use case, I highly recommend exploring the ggplot2 package for more advanced and customizable graphics.
My question deals with the color2d.matplot function from the plotrix package. The function is documented here.
I have this output:
Produced by this code:
library(plotrix)
# model parameters
spaces <- 400
agents<- 300
prop_black = 0.5
prop_white = 1 - prop_black
tolerance <- 0.6
# creating matrix of types
group<-c(rep(0,spaces-agents),rep(1,prop_black*agents),rep(2,prop_white*agents))
grid<-matrix(sample(group,400,replace=F), ncol=20)
# plotting
color2D.matplot(grid, ylab="", xlab = "", axes=F)
plot(runif(100,0,1),ylab="Happy",xlab="Time",col="white",ylim=c(0,1))
Notice that my grid contains values of 0,1,2 only.
How do I make it so that:
All values of 0 map to white squares.
All values of 1 map to red squares.
All values of 2 map to blue squares.
I tried to figure it out by looking at these examples but didn't have much luck.
You may index a colour vector with the values in your matrix. A smaller example:
color2D.matplot(m, cellcolors = c("white", "red", "blue")[m + 1])
Data:
set.seed(7)
m <- matrix(sample(0:2, 9, replace = TRUE), nrow = 3, ncol = 3)
m
# [,1] [,2] [,3]
# [1,] 2 0 1
# [2,] 1 0 2
# [3,] 0 2 0
One thing I could think of is to specify the color for each cell.
cellcolors <- unlist(grid)
cellcolors <- ifelse(cellcolors == 0, "white", ifelse(cellcolors == 1, "red", "blue"))
color2D.matplot(grid, ylab="", xlab = "", axes=F, cellcolors = cellcolors)
I want to create a vector of colors to then apply it to a barplot. I have created a color range:
color.function <- colorRampPalette(c("blue", "white", "red"))
And then I would like to get the specific colors for specific values contained in a range. For example, let's say that I want the color range to span -10 to 10. Then I want to get the colors for -7, -4.5 and 2 (for example).
How could I do that? I have tried this:
col.seq <- seq(-10, 10, 0.1)
cuts <- cut(c(-7,-4.5,2), breaks = length(col.seq))
colors <- colorRampPalette(c("blue", "white", "red"))(length(col.seq))
levels(colors) <- cuts
colors
but it seems to just give a color per break on my palette.
Any help is appreciated!
To get correct colour for you numeric value you need to find it's idex in the sequence vector you started with.
You can get it with rounding and which:
color.function <- colorRampPalette(c("blue", "white", "red"))
col.seq <- round(seq(-10, 10, 0.1), 1)
colors <- colorRampPalette(c("blue", "white", "red"))(length(col.seq))
x <- 6.5323
x.map <- round(x, 1)
x.index <- which(col.seq == x.map)
colors[x.index]
# [1] "#FF5959"
x <- 1.7323
x.map <- round(x, 1)
x.index <- which(col.seq == x.map)
colors[x.index]
# [1] "#FFD3D3"
I am plotting boxplots of fish biomass by reefname, in order of median biomass. All reefnames (sites) are either in or out of a MPA, e.g MPA="1" or MPA=="0". Currently all plots show green.
How can I show MPA=="0" sites as blue and MPA=="1" as green for example. While maintaining the order of the fish biomass.
MPA <- factor(Fish$MPA)
bymedian <- with(Fish, reorder(ReefName, log10(Biomassm+1)), median)
boxplot(log10(Biomassm+1) ~ bymedian, data = Fish,
xlab = "ReefName", ylab = "Biomassm",
main = "Biomassm in Caribbean", varwidth = TRUE,
col=(c("darkgreen")), las=3, cex.axis=0.3)
Thank you
It might be a better idea to use the ggplot2 package for this. Your code would then look like this:
ggplot(data=Fish, aes(x=reorder(ReefName, log10(Biomassm+1)), median), y=Biomassm, fill=MPA)) +
geom_boxplot() +
scale_y_log10("Biomassm") +
xlab("ReefName") +
scale_fill_manual(values=c("blue", "green")) +
ggtitle("Biomassm in Caribbean")
Here's a set of boxplots coloured depending on the value of MPA:
# generate some data
set.seed(1)
X = matrix(rnorm(100), ncol=10)
# order by median
X = X[,order(apply(X, 2, median))]
# some fake MPA values
MPA = round(runif(n=10, min=0, max=1))
# generate boxplots and check if MPA==1
boxplot(X, col=ifelse(test=MPA==1, yes='green', no='blue'))
# add legend
legend(x='bottomleft', fill=c('green','blue'), legend=c('MPA=1', 'MPA=0'), inset=c(0.01))
The output of ifelse is a vector of colours according to the MPA values and these are used to colour the boxes:
[1] "blue" "blue" "green" "blue" "blue" "green" "green" "blue" "blue" "green"
I have some data that I want to plot (e.g. plot(x,y)) but I have some criteria that I want to color by depending on the values in vector z which looks like c(1, 0, 1, 1, 1, 1, 0, NA ,0 ,0, .....) etc.
Is there some way I can choose what color the 1's are going to be and what color the 0's are going to be?
Thanks
I know this has already been answered but here is some very intuitive code with a plot for reference.
#Let's create some fictional data
x = rbinom(100,1,.5)
x[round(runif(10)*100)] = NA
#Assign colors to 1's and 0's
colors = rep(NA,length(x))
colors[x==1] = "blue"
colors[x==0] = "red"
#Plot the vector x
plot(x,bg=colors,pch=21)
You want to get a vector of colors as long as the x and y vectors, for example as follows:
z[is.na(z)] = 2
zcol = c("red", "blue", "black")[z + 1]
Then you can simply do:
plot(x, y, col=zcol)
Maybe I am missing something, but I think you want:
plot(x,y,col=ifelse(z==0,'zerocolour','onecolour'))
where you replace the two colours with red and blue or whatever.
I don't think the NA will be plotted, so you don't have to worry about those.
For more colours, you could create a little mapping data.frame with the unique values of z, and then merge z with the data.frame. Here is an example with two colours:
map<-data.frame(z=c(0,1),col=c('red','blue'))
plot(x,y,col=merge(z,map)$col)
Using the ggplot2 package
require(ggplot2)
df <- data.frame(x = c(1, 2, 3, 4, 5), y = c(2, 3, 4, 6, 7), z = c(1, 0 , 1, 0 , NA))
df$z[is.na(df$z)] = 2
ggplot(df, aes(x, y, color = as.factor(z))) + geom_point()
You can supply vector of colors to argument col= and then use z to select colors. Used paste() to convert NA to character and then as.factor() to interpret those characters as 1, 2 and 3.
x<-c(1,2,3,4,5)
y<-c(1,2,3,4,5)
z<-c(1,0,NA,1,1)
plot(x,y,col=c("red","green",'black')[as.factor(paste(z))],pch=19,cex=3)
str(as.factor(paste(z)))
Factor w/ 3 levels "0","1","NA": 2 1 3 2 2