Add Text to Horizontal Barplot in R, Y-Axis at Different Scale

add text to horizontal barplot in R, y-axis at different scale?

By chacking the documentation of barplot, you can see that it has an invisible return value: the midpoints of the bars. You can use those to add additional information to the plot.

x <- runif(10, 0,1) 
y <- matrix(c(x, 1-x), nrow=2, ncol=10, byrow=TRUE)
bp <- barplot(y, horiz=TRUE, beside=FALSE, names.arg=seq(1,10,1), las=1,
xlim=c(0, 1.2))
text(x, bp, signif(x,2), pos=4)
bp

R: horizontal barplot with y-axis-labels next to every bar

Look at ?barplot arguments names.arg.

Some example data:

transComp <- matrix(sample(3*36), nrow=3, ncol=36)     
colnamesbarplot <- as.character(1:36)

The barplot:

barplot(transComp,space=c(0,2),legend.text=TRUE,beside=TRUE,horiz=TRUE,
density=NA,
col=c("red1","red4","green3"),
xlab="crimes per 100,000 inhabitants",
ylab="districts and years",
axes=TRUE, names.arg=colnamesbarplot, cex.names=0.5, las=1)

Since you have many columns to plot you should set cex.names to make the labels smaller.
The argument las=1 rotates the labels by 90 degrees.

R horizontal barplot with axis labels split between two axis

We can accomplish this using mtext:

generate data

Since you didn't include your data in the question I generated my own dummy data set. If you post a dput of your data, we could adapt this solution to your data.

set.seed(123)
df1 <- data.frame(x = rnorm(20),
y = LETTERS[1:20])
df1$colour <- ifelse(df1$x < 0, 'blue', 'red')

make plot

bp <- barplot(df1$x, col = df1$colour, horiz = T)
mtext(side = ifelse(df1$x < 0, 2, 4),
text = df1$y,
las = 1,
at = bp,
line = 1)

Sample Image

Can you put labels between horizontal bars?

Using facet:

#fix the order of factors
data3$System <- factor(data3$System, levels = c("Zivildienst", "Katastrophenschutz"))

#plot with facets
ggplot(data3, aes(x = System, y = Anzahl, fill = Einstellung)) +
geom_bar(stat = "identity") +
geom_text(aes(y = pos, label = label), size = 4) +
coord_flip() +
facet_wrap(vars(System), ncol = 1, scales = "free_y") +
scale_x_discrete(expand = c(0, 0)) + # make bar "fuller"
scale_y_continuous(expand = c(0, 0)) + # make bar "fuller"
scale_fill_manual(values = cbPalette) +
ggtitle("Werden Sie sich für die Alternative entscheiden?",
subtitle = "2000 Männer befragt") +
theme(panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.title.y = element_blank(),
aspect.ratio = .3,
axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
strip.background = element_rect(fill = NA),# remove facet strip background
strip.text = element_text(hjust = 0) # left align the facet strip text
)

Sample Image

How to create a barplot in R with frequencies on the y-axis not the densities?

Try this approach using ggplot2 and dplyr pipelines. You need to transform your vector to dataframe and then summarise to obtain the counts. After that the plot can be sketched using geom_bar() and geom_text() to add the desired labels. Here the code:

library(ggplot2)
library(dplyr)
#Data
bloodgroup <- c("O", "A", "A", "O", "O",
"B", "B", "A", "A", "A",
"A", "O", "O", "O", "B",
"O", "O", "A", "O", "A",
"A", "O", "AB", "B", "O",
"AB", "B", "O", "A", "AB")
#Code
bloodgroup %>% as.data.frame %>%
rename(Var='.') %>%
group_by(Var) %>% summarise(N=n()) %>%
ggplot(aes(x=Var,y=N,fill=Var))+
geom_bar(stat = 'identity',color='black')+
scale_y_continuous(labels = scales::comma_format(accuracy = 2))+
geom_text(aes(label=N),vjust=-0.25,fontface='bold')+
theme_bw()+
theme(axis.text = element_text(color='black',face='bold'),
axis.title = element_text(color='black',face='bold'),
legend.text = element_text(color='black',face='bold'),
legend.title = element_text(color='black',face='bold'))

Output:

Sample Image

Or with base R:

#Code 2
xx <- barplot(table(bloodgroup),ylim=c(0, 14))
coords <- as.numeric(table(bloodgroup))
text(x = xx, y = coords, label = coords, cex = 0.8,pos = 3, col = "red")

Output:

Sample Image

Creating barplot with dual y-axis

Try this tidyverse approach with ggplot2. The key for double axis plots is to have a scaling factor between the variables to be showed in the plot. Here the code:

library(tidyverse)
#Scaling factor
sf <- max(df$V2)/max(df$V3)
#Transform
DF_long <- df %>%
mutate(V3 = V3*sf) %>%
pivot_longer(names_to = "y_new", values_to = "val", V2:V3)
#Plot
ggplot(DF_long, aes(x=V1)) +
geom_bar( aes(y = val, fill = y_new, group = y_new),
stat="identity", position=position_dodge(),
color="black", alpha=.6) +
scale_fill_manual(values = c("blue", "red")) +
scale_y_continuous(name = "V2",labels = scales::comma,sec.axis = sec_axis(~./sf, name="V3",
labels = scales::comma))+
labs(fill='variable')+
theme_bw()+
theme(legend.position = 'top',
plot.title = element_text(color='black',face='bold',hjust=0.5),
axis.text = element_text(color='black',face='bold'),
axis.title = element_text(color='black',face='bold'),
legend.text = element_text(color='black',face='bold'),
legend.title = element_text(color='black',face='bold'))+
ggtitle('My barplot')

Output:

Sample Image

Some data used:

#Data
df <- structure(list(V1 = c("abc", "xyz", "def"), V2 = c(862054L, 760369L,
488089L), V3 = c(111552197L, 163135388L, 130846735L)), class = "data.frame", row.names = c(NA,
-3L))

How to display the frequency at the top of each factor in a barplot in R

You are having problems because dat$freqs is a factor, even though it's printed representation 'looks like' it's numeric. (It's almost always helpful to type str(foo) -- here str(dat) or str(dat$freqs) -- to have a look at the real structure of the data you're working with.)

In any case, once you've converted dat$freq to class "numeric", constructing the plot becomes straightforward:

## Make the frequencies numbers (rather than factors)
dat$freqs <- as.numeric(as.character(dat$freqs))
## Find a range of y's that'll leave sufficient space above the tallest bar
ylim <- c(0, 1.1*max(dat$freqs))
## Plot, and store x-coordinates of bars in xx
xx <- barplot(dat$freqs, xaxt = 'n', xlab = '', width = 0.85, ylim = ylim,
main = "Sample Sizes of Various Fitness Traits",
ylab = "Frequency")
## Add text at top of bars
text(x = xx, y = dat$freqs, label = dat$freqs, pos = 3, cex = 0.8, col = "red")
## Add x-axis labels
axis(1, at=xx, labels=dat$fac, tick=FALSE, las=2, line=-0.5, cex.axis=0.5)

Sample Image

Adding a line to a barplot with two different x coordinates in R

It is a bit complicated to understand what you want... I will try to help you with these two hints:

  1. The x-values at which the bars are plotted are returned by the function barplot. So, to use them in a latter plot, you can just store them with

    bp = barplot(...)

    and use them latter in the call to lines:

    lines(bp, y.data, ...)

  2. You will find that the parts of the lines going above the bars are not plotted, because y values are cropped by default when the view is initialize with barplot. There are several possible workarounds:

    bp = barplot(..., ylim=range(data)+c(-1,1) ) # to set the y-limits during the call to barplot

    or:

    lines(..., xpd=T) # to allow drawing in the plot margin

Finally, a minimal working example is displayed below:

data = c(2.5, .5, .5, 3.5, 6)
bp = barplot(data, names.arg=c("0-1","1-2", "2-3", "3-4", "4-5"),
ylim = range(data)+c(-1,1) )
lines(bp, c(3, .1, .1, 4, 6.5), lty=2, lwd=2)

Sample Image



Related Topics



Leave a reply



Submit