barcols <- c("green","red","purple")
barcols
barplot(table(gender$Alert.Level, gender$Gender),las=1, beside= TRUE, ylab= "Frequency", xlab="gender", cex.names=0.7, main="Frequency of violations by gender" , col=barcols)
How would you go about adding a legend to the top left where green= alert level 1, red = alert level 2 and purple = alert level 3
Here are two plots, one with a vertical legend and the other with a horizontal legend.
Note that in the first plot the y axis limits are extended in order to have the legend not overplot the bars.
set.seed(2022)
al <- c("alert level 1", "alert level 2", "alert level 3")
al <- factor(al, levels = al)
gender <- data.frame(Alert.Level = sample(al, 100, TRUE),
Gender = sample(c("Female", "Male", "Unknown"), 100, TRUE))
barcols <- c("green","red","purple")
barplot(
table(gender$Alert.Level, gender$Gender),
las=1, beside = TRUE,
#
ylim = c(0, 17),
#
ylab= "Frequency", xlab="gender",
cex.names=0.7,
main="Frequency of violations by gender",
col = barcols
)
lgd <- sort(unique(gender$Alert.Level))
legend("topleft", legend = lgd, fill = barcols)
barplot(
table(gender$Alert.Level, gender$Gender),
las=1, beside= TRUE,
#
ylim = c(0, 17),
#
ylab= "Frequency", xlab="gender",
cex.names=0.7,
main="Frequency of violations by gender",
col = barcols
)
legend("topleft", legend = lgd, fill = barcols, horiz = TRUE)
Created on 2022-03-23 by the reprex package (v2.0.1)
Related
I ran a distance-based RDA using capscale() in the vegan library in R and I am trying to plot my results as a custom triplot. I only want numeric or continuous explanatory variables to be plotted as arrows/vectors. Currently, both factors and numeric explanatory variables are being plotted with arrows, and I want to remove arrows for factors (site and year) and plot centroids for these instead.
dbRDA=capscale(species ~ canopy+gmpatch+site+year+Condition(pair), data=env, dist="bray")
To plot I extracted % explained by the first 2 axes as well as scores (coordinates in RDA space)
perc <- round(100*(summary(spe.rda.signif)$cont$importance[2, 1:2]), 2)
sc_si <- scores(spe.rda.signif, display="sites", choices=c(1,2), scaling=1)
sc_sp <- scores(spe.rda.signif, display="species", choices=c(1,2), scaling=1)
sc_bp <- scores(spe.rda.signif, display="bp", choices=c(1, 2), scaling=1)
I then set up a blank plot with scaling, axes, and labels
dbRDAplot<-plot(spe.rda.signif,
scaling = 1, # set scaling type
type = "none", # this excludes the plotting of any points from the results
frame = FALSE,
# set axis limits
xlim = c(-1,1),
ylim = c(-1,1),
# label the plot (title, and axes)
main = "Triplot db-RDA - scaling 1",
xlab = paste0("db-RDA1 (", perc[1], "%)"),
ylab = paste0("db-RDA2 (", perc[2], "%)"))
Created a legend and added points for site scores and text for species
pchh <- c(2, 17, 1, 19)
ccols <- c("black", "red", "black", "red")
legend("topleft", c("2016 MC", "2016 SP", "2018 MC", "2018 SP"), pch = pchh[unique(as.numeric(as.factor(env$siteyr)))], pt.bg = ccols[unique(as.factor(env$siteyr))], bty = "n")
points(sc_si,
pch = pchh[as.numeric(as.factor(env$siteyr))], # set shape
col = ccols[as.factor(env$siteyr)], # outline colour
bg = ccols[as.factor(env$siteyr)], # fill colour
cex = 1.2) # size
text(sc_sp , # text(sc_sp + c(0.02, 0.08) tp adjust text coordinates to avoid overlap with points
labels = rownames(sc_sp),
col = "black",
font = 1, # bold
cex = 0.7)
Here is where I add arrows for explanatory variables, but I want to be selective and do so for numeric variables only (canopy and gmpatch). The variables site and year I want to plot as centroids, but unsure how to do this. Note that the data structure for these are definitely specified as factors already.
arrows(0,0, # start them from (0,0)
sc_bp[,1], sc_bp[,2], # end them at the score value
col = "red",
lwd = 2)
text(x = sc_bp[,1] -0.1, # adjust text coordinate to avoid overlap with arrow tip
y = sc_bp[,2] - 0.03,
labels = rownames(sc_bp),
col = "red",
cex = 1,
font = 1)
#JariOksanen thank you for your answer. I was able to use the following to fix the problem
text(dbRDA, choices = c(1, 2),"cn", arrow=FALSE, length=0.05, col="red", cex=0.8, xpd=TRUE)
text(dbRDA, display = "bp", labels = c("canopy", "gmpatch"), choices = c(1, 2),scaling = "species", arrow=TRUE, select = c("canopy", "gmpatch"), col="red", cex=0.8, xpd = TRUE)
#JariOksanen thank you for your answer. I was able to use the following to fix the problem
text(dbRDA, choices = c(1, 2),"cn", arrow=FALSE, length=0.05, col="red", cex=0.8, xpd=TRUE)
text(dbRDA, display = "bp", labels = c("canopy", "gmpatch"), choices = c(1, 2),scaling = "species", arrow=TRUE, select = c("canopy", "gmpatch"), col="red", cex=0.8, xpd = TRUE)
I've created the stacked bar chart below. I would like to remove the white border line between the two colors of the bar. Is this possible?
counts<- structure(list(
A = c(51,11),
B = c(51,11),
C = c(31,9),
D = c(46,3),
E = c(20,3),
F = c(57,29),
G = c(31,6),
H = c(6,0)),
.Names = c("I'm sure of myself when I do science activities",
"I would consider a career in science",
"I expect to use science when I get out of school",
"Knowing science will help me earn a living",
"I will need science for my future work",
"I know I can do well in science",
"Science will be important to me in my life’s work",
"I cannot do a good job with science"
),
class = "data.frame",
row.names = c(NA, -2L)) #4L=number of numbers in each letter vector#
attach(counts)
print(counts)
# barplot
colors <- c("slategray3","dodgerblue4")
counts <- counts[, order(colSums(counts))]
xFun <- function(x) x/2 + c(0, cumsum(x)[-length(x)])
par(mar=c(2, 22, 4, 2) + 0.1) # this sets margins to allow long labels
byc <- barplot(as.matrix(counts), horiz=TRUE, col=colors, #main="N=35"#,
border=FALSE, las=1, xaxt='n',
ylim = range(0, 12), xlim = range(-10, 100),
width = 1.35)
# labels
labs <- data.frame(x=as.vector(sapply(counts, xFun)), # apply `xFun` here
y=rep(byc, each=nrow(counts)), # use `byc` here
labels=as.vector(apply(counts, 1:2, paste0, "%")),
stringsAsFactors=FALSE)
labs$labels[labs$labels %in% paste0(0:(8*100)/100, "%")] <- "" #masks labels <8
invisible(sapply(seq(nrow(labs)), function(x) # `invisible` prevents unneeded console
output
text(x=labs[x, 1:2], labels=labs[x, 3], cex=.9, font=2, col=0)))
#adds % to scale
scale <- seq(0, 100, by = 20)
axis(side = 1, at = scale, labels = paste0(scale, "%"), cex.axis = 1)
#this adds gridlines
grid(nx = NULL, ny = nx, col = "lightgray", lty = "dotted",
lwd = par("lwd"), equilogs = TRUE)
# legend (set `xpd=TRUE` to plot beyond margins!)
legend(15,14.5, legend=c("Agree","Strongly Agree"),
fill=colors, horiz = T, bty='n', xpd=T)
You could try: border=NA,
byc <- barplot(as.matrix(counts), horiz=TRUE, col=colors, #main="N=35"#,
border=NA, las=1, xaxt='n',
ylim = range(0, 12), xlim = range(-10, 100),
width = 1.35)
I would like to automate data labels (with % signs) placed on top of the vertical bars produced with the code below. Is there a way to do this?
H <- c(61,89,94,89) # Create the data for the chart.#
M <- c("Pre-Calculus",
"College Algebra",
"Intermediate Algebra",
"Elementary Algebra")
par(mar=c(5.1, 10, 4, 1.1))
barplot(H, col =c("dodgerblue4" ), ylim = range(0,110),
names.arg = M, horiz = F,
family="Arial", border = NA, xlim = range(0,5), las=1,
axes = T, ylab = 'Passing Percent')
Use the text() function. See this SO post for reference
bp <- barplot(H, col =c("dodgerblue4" ), ylim = range(0,110),
names.arg = M, horiz = F,
family="Arial", border = NA, xlim = range(0,5), las=1,
axes = T, ylab = 'Passing Percent')
text(bp, H + 5, paste(H, "%", sep=""))
I want my boxplot to have the y axis to go from 0 to 20,000 , but when I add the argument ylim = c(0,20000), my entire boxplot disappears.
Here is my code:
bp.gender <- boxplot(
music_data.frame$Income ~ music_data.frame$Gender,
xlab = "Gender",
ylab = "Income",
main = "Income distribution for Gender",
col = "red",
ylim = c(0,20000)
I want to add labels to the columns of my barplot. Since there are 2 groups each pair of columns will share the same label, i.e 7 labels from "dislike very much" to "like very well".
Since labels titles are quite long I intended to rotate them using the text() function but I cannot get it to display correctly. Here is the code:
A <- c(0, 1, 0, 1, 14, 44, 42)
B <- c(0, 0, 0, 2, 14, 41, 45)
x <- rbind(A, B)
dd.names <- c("Dislike very much", "Strongly dislike", "Dislike", "Neither like nor dislike", "Like", "Like well", "Like very well")
bp <- barplot(x,
beside = TRUE, # Plot the bars beside one another; default is to plot stacked bars
space=c(0.2,0.8), # Amount of space between i) bars within a group, ii) bars between groups
legend = c("Fish cake containing sugar kelp", "Control fish cake"),
args.legend = list(x = "topleft", bty = "n", inset=c(0.1, 0.1)), # bty removes the frame from the legend
xlab = "",
ylab = "Number of scores",
ylim = range(0:50), # Expand the y axis to the value 50
main = "Score results from taste experiments of fish cakes")
text(bp, par("usr")[1], pos = 1, offset = 2, labels = dd.names, adj = 0.5, srt = 25, cex = 0.8, xpd = TRUE)
IMO you're better off rotating the graph.
par(mar=c(3,8,1,1),mgp=c(1.5,.5,0))
bp <- barplot(x,
beside = TRUE,
space=c(0.2,0.8),
legend = c("Fish cake containing sugar kelp", "Control fish cake"),
args.legend = list(x = "bottom", bty = "n", inset=c(0.1, 0.1)),
ylab = "",
xlab = "Number of scores",
xlim = range(0:50), # Expand the y axis to the value 50
main = "Score results from taste experiments of fish cakes",
horiz = TRUE)
text(rep(0,length(dd.names)),bp[1,], par("usr")[3], pos = 2,
labels = dd.names, cex = 0.8, xpd = TRUE)
In an unsolicited act of evangelism, here is a ggplot solution.
library(ggplot2)
library(reshape2) # for melt(...)
library(grid) # for unit(...)
gg <- melt(data.frame(dd.names,t(x)),id="dd.names")
gg$dd.names <- with(gg,factor(dd.names,levels=unique(dd.names)))
ggplot(gg,aes(x=dd.names,y=value))+
geom_bar(aes(fill=variable),stat="identity",position="dodge")+
coord_flip()+
scale_fill_manual(name="",values=c("grey30","grey70"),
labels=c("Fish cake containing sugar kelp", "Control fish cake"))+
labs(title="Score results from taste experiments of fish cakes",
x="",y="Number of scores")+
theme_bw()+theme(legend.position = c(1,0),legend.justification = c(1,0),
legend.key.height=unit(0.8,"lines"))