barplot labels in r: issues with displaying rotated labels using text() - r

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"))

Related

RDA triplot in R- plot only numeric explanatory variables as arrows; factors as centroids

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)

Create one-dimensional plot in R with text labels

I want to create a simple one-dimensional plot in R ranging from 0 to ten, with a scale (small lines for integer values 1,2, etc.), a slightly higher line for 5 (the median) and slightly higher than all of the other for 0 and 10. Then I want to fill this plot with a few points representing values like 2, 4, 5, 6, 8, and a text above each one of them with corresponding labels (like "party voted", "closest party", "individual 1", "expert", "individual 2"). It can be smaller labels, like "PV", "CP", etc.
I would like to have control over shape and color (say in data-points 4 and 6 I have a circle filled in black but in position 2 I have a not filled square, in position 5 I have a green circle filled-in, and in position 8 I have a black triangle, also filled). I would like to have 0, 10 and 5 marked in the labels as well.
A very rough representation of what I am trying to draw is in the image below (it has all the elements I want, at least).
In this Stack Overflow question there is some code on one-dimension plot, I have tried to adapt it to what I need but didn't get to it
I've assumed from the link in the question that you are looking for a base R solution.
There may be more efficient solutions but this seems to get you where you want.
I've avoided the need for arrows by forcing the labels to run over two lines and reducing the text size on the plot so they do not overlap.
You could manage this with arrows if need be, but this seems it will need a lot of extra code.
# data
df <- data.frame(desc = c("Party voted", "Closest party", "Individual 1", "Expert", "Individual 2"),
score = c(2, 4, 5, 6, 8),
y = 1)
# add line break to labels
df$desc <- gsub("\\s", "\n", df$desc)
plot(df$score,
df$y,
# type = "o",
xlim = c(0, 10),
pch = c(1, 21,21,21, 24),
col = c("black", "black", "green", "black", "black"),
bg = c("black", "black", "green", "black", "black"),
cex = 1.5,
xaxt = "n", #remove tick marks
yaxt = "n",
ylab = '', # remove axis labels
xlab = '',
bty = "n") # remove bounding box
axis(side = 1,
0:10,
pos = df$y,
labels = FALSE,
tck = 0.02)
axis(side = 1,
0:10,
pos = df$y,
labels = c(0, rep("", 4), 5, rep("", 4), 10),
tck = -0.02)
axis(side = 1,
c(0, 5, 10),
pos = df$y,
labels = FALSE,
tck = 0.05)
axis(side = 1,
c(0, 5, 10),
pos = df$y,
labels = FALSE,
tck = -0.05)
text(x = df$score,
y = df$y,
labels = df$desc,
pos = 3,
offset = 1,
cex = 0.75)
Created on 2021-04-28 by the reprex package (v2.0.0)

Is it possible to remove stacked bar border line?

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)

How To Make Histogram Bins in R-Studio Only Use Integers

I am attempting to create several histograms that display the effects a drug has on the frequency of heart attacks.
Currently, R is organizing my data into the bins [0 - 0.5, 0.5 - 1.0, 1.0 - 1.5, etc.], but I would like for it to only use integer values: [0 - 1, 1 - 2, 2 - 3, etc.].
I have tried using the xaxt="n" argument and the axis() function. They "worked," but they did not solve the problem above. I also tried to use breaks=seq(0,5,l=6), but this converted my y-axis from frequency into density.
Here is the code for my latest two attempts:
hist(fourTrials$red_5, breaks=5, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue")
hist(fourTrials$red_5, breaks=seq(0,5,l=6), freq = F, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue",yaxs="i",xaxs="i")
Thanks for any help!
I believe that what you want is:
hist(fourTrials$red_5, breaks=0:4, freq = TRUE, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400",
col = "lightblue", yaxs="i", xaxs="i")

How to replace axis in gap.barplot in R

I've been trying to figure out how to replace the x-axis in gap.barplot in R. First, I have an issue with labeling:
Attached is my code:
Samples Conc stdlo stdhi
SampA 5000 0 0
SampB 100 0 11
SampC 80 0 20
rm(list=ls())
library(plotrix)
C.dat <- read.csv("G:/...../C.csv", head = TRUE)
C.lab = C.dat$Samples
C.conc = C.dat$Conc
C.lostd = C.dat$stdlo
C.histd = C.dat$stdhi
par(mar=c(6,6,5,2))
barplot = gap.barplot(C.conc, gap = c(200,1000), xlab = "Samples",
ylab ="C Conentration (pg/mL)", main = "C in X and Y", las = 2,
xlim = c(0,4), ytics = c(0,1000,1500,5100), cex.lab = 1.5)
mtext("SampA", side = 1, at= 1.0, cex=1.0)
mtext("SampB", side = 1, at= 2.0, cex=1.0)
mtext("SampC", side = 1, at= 3.0, cex=1.0)
arrows(barplot,C.conc-0 ,barplot,C.conc+C.histd,code=2,angle=90,length=.1)
My biggest issue is when I stick in axes = FALSE in the gap.barplot parameters, it gives me a warning and no plot is produced. I want to get rid of the "1 2 3" axes label and the tick marks.
Also, if anyone has any idea how to move the y-axis label a bit more to the left, that would be nice.
Any suggestions?
You may try this. I call your data frame df.
I added xaxt = "n" to the gap.barplot call.
From ?par:
xaxt: A character which specifies the x axis type. Specifying "n" suppresses plotting of the axis.
Then axis is used to add an x axis with labels at positions at, but with no ticks (tick = FALSE). The label for the y axis is added with mtext
library(plotrix)
par(mar=c(6,6,5,2))
gap.barplot(df$Conc, gap = c(200,1000),
xlab = "Samples", ylab ="", main = "C in X and Y", las = 2,
xlim = c(0, 4), ytics = c(0, 1000, 1500, 5100), cex.lab = 1.5,
xaxt = "n")
axis(side = 1, at = seq_along(df$Sample), labels = df$Sample, tick = FALSE)
mtext("C Concentration (pg/mL)", side = 2, line = 4)

Resources