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)
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
)
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:
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:
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:
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)
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:
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, ...)
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)
Related Topics
R Grep: Is There an and Operator
Protect/Encrypt R Package Code for Distribution
What Does "Error: Object '<Myvariable>' Not Found" Mean
Use a Variable Within a Plotmath Expression
Make Readline Wait for Input in R
Create a Time Interval of 15 Minutes from Minutely Data in R
Plots Generated by 'Plot' and 'Ggplot' Side-By-Side
R: Lm() Result Differs When Using 'Weights' Argument and When Using Manually Reweighted Data
How to Redirect Console Output to a Variable
How to Add a Factor Column to Dataframe Based on a Conditional Statement from Another Column
R - When Trying to Install Package: Internetopenurl Failed
Rcpp Function Check If Missing Value
Rstudio Shiny List from Checking Rows in Datatables
R: How to Run Some Code on Load of Package
Sparse Matrix to a Data Frame in R