I'm having an issue with data labels incorrectly ordering using ggplot2.
Unfortunately, other SE Q&As on this topic are not very insightful(example), so I'm having to reach out with a reprex. I have the following data:
df = as.data.frame(structure(list(geotype = c('urban','urban','urban','urban','suburban','suburban','suburban','suburban'),
limitations = c('all','some','all','some','all','some','all','some'),
metric = c('lte','lte','5g','5g','lte','lte','5g','5g'),
capacity=c(12,11,5,4,14,10,5,3))))
If I then try to plot this data using this code:
ggplot(df, aes(x = geotype, y = capacity, fill=metric)) + geom_bar(stat="identity") +
facet_grid(~limitations) +
geom_text(data = df, aes(geotype, capacity + 2, label=capacity), size = 3)
I get this incorrect labelling order:
I've played with the ordering of the variables for ages (e.g. rev(capacity)) but I can't fix the issue. Can anyone provide a more comprehensive answer for the whole SE community as to how to deal with label ordering?
You need to call the position argument in geom_text to match the filled aesthetics data with geom_bar and to let the function know the data is stacked.
ggplot(df, aes(x = geotype, y = capacity, fill=metric)) +
geom_bar(stat="identity") +
geom_text(data = df, aes(geotype, capacity, label=capacity), size = 3, vjust = 2,
position = position_stack()) +
facet_grid(~limitations)
You can set the labels in the mail ggplot aes
ggplot(df, aes(x = geotype, y = capacity, fill = metric, label = capacity ) ) +
geom_col() +
geom_text( size = 3, position = position_stack( vjust = 0.5 ) ) +
facet_grid( ~limitations )
Something like this? The position stack.
g <- ggplot(df, aes(x = geotype, y = capacity, fill = metric, label =
capacity))
g + geom_col() + facet_grid(~limitations) +
geom_text(size = 3, vjust =3, position = position_stack())
Related
I want to separately plot data in a bubble plot like the image right (I make this in PowerPoint just to visualize).
At the moment I can only create a plot that looks like in the left where the bubble are overlapping. How can I do this in R?
b <- ggplot(df, aes(x = Year, y = Type))
b + geom_point(aes(color = Spp, size = value), alpha = 0.6) +
scale_color_manual(values = c("#0000FF", "#DAA520", "#228B22","#E7B888")) +
scale_size(range = c(0.5, 12))
You can have the use of position_dodge() argument in your geom_point. If you apply it directly on your code, it will position points in an horizontal manner, so the idea is to switch your x and y variables and use coord_flip to get it in the right way:
library(ggplot2)
ggplot(df, aes(y = as.factor(Year), x = Type))+
geom_point(aes(color = Group, size = Value), alpha = 0.6, position = position_dodge(0.9)) +
scale_color_manual(values = c("#0000FF", "#DAA520", "#228B22","#E7B888")) +
scale_size(range = c(1, 15)) +
coord_flip()
Does it look what you are trying to achieve ?
EDIT: Adding text in the middle of each points
To add labeling into each point, you can use geom_text and set the same position_dodge2 argument than for geom_point.
NB: I use position_dodge2 instead of position_dodge and slightly change values of width because I found position_dodge2 more adapted to this case.
library(ggplot2)
ggplot(df, aes(y = as.factor(Year), x = Type))+
geom_point(aes(color = Group, size = Value), alpha = 0.6,
position = position_dodge2(width = 1)) +
scale_color_manual(values = c("#0000FF", "#DAA520", "#228B22","#E7B888")) +
scale_size(range = c(3, 15)) +
coord_flip()+
geom_text(aes(label = Value, group = Group),
position = position_dodge2(width = 1))
Reproducible example
As you did not provide a reproducible example, I made one that is maybe not fully representative of your original dataset. If my answer is not working for you, you should consider providing a reproducible example (see here: How to make a great R reproducible example)
Group <- c(LETTERS[1:3],"A",LETTERS[1:2],LETTERS[1:3])
Year <- c(rep(1918,4),rep(2018,5))
Type <- c(rep("PP",3),"QQ","PP","PP","QQ","QQ","QQ")
Value <- sample(1:50,9)
df <- data.frame(Group, Year, Value, Type)
df$Type <- factor(df$Type, levels = c("PP","QQ"))
I'm struggling with the following issue:
I want to plot two histograms, but since the statistics of one of the two classes is much less than the other I need to add a second y-axis to allow a direct comparison of the values.
I report below the code I used at the moment and the result.
Thank you in advance!
ggplot(data,aes(x= x ,group=class,fill=class)) + geom_histogram(position="identity",
alpha=0.5, bins = 20)+ theme_bw()
Consider the following situation where you have 800 versus 200 observations:
library(ggplot2)
df <- data.frame(
x = rnorm(1000, rep(c(1, 2), c(800, 200))),
class = rep(c("A", "B"), c(800, 200))
)
ggplot(df, aes(x, fill = class)) +
geom_histogram(bins = 20, position = "identity", alpha = 0.5,
# Note that y = stat(count) is the default behaviour
mapping = aes(y = stat(count)))
You could scale the counts for each group to a maximum of 1 by using y = stat(ncount):
ggplot(df, aes(x, fill = class)) +
geom_histogram(bins = 20, position = "identity", alpha = 0.5,
mapping = aes(y = stat(ncount)))
Alternatively, you can set y = stat(density) to have the total area integrate to 1.
ggplot(df, aes(x, fill = class)) +
geom_histogram(bins = 20, position = "identity", alpha = 0.5,
mapping = aes(y = stat(density)))
Note that after ggplot 3.3.0 stat() probably will get replaced by after_stat().
How about comparing them side by side with facets?
ggplot(data,aes(x= x ,group=class,fill=class)) +
geom_histogram(position="identity",
alpha=0.5,
bins = 20) +
theme_bw() +
facet_wrap(~class, scales = "free_y")
I came across this question the other day and tried to re-create it for myself. ggplot, facet, piechart: placing text in the middle of pie chart slices
. My data is in a very similar format, but sadly the accepted answer did not help, hence why I am re posting.
I essentially want to create the accepted answer but with my own data, yet the issue I run into is that coord_polar does not support free scale. Using the first answer:
I tried it using the second version of the answer, with the ddplyr version, but I also do not get my desired output. Using the second answer:
Clearly none of these has the desired effect. I would prefer to create one as with size pie charts, but only showed four as an example, follows: .
This I did in excel, but with one legend, and no background grid.
Code
title<-c(1,1,2,2,3,3,4,4,5,5,6,6)
type<-c('A','B','A','B','A','B','A','B','A','B','A','B')
value<-c(0.25,0.75,0.3,0.7,0.4,0.6,0.5,0.5,0.1,0.9,0.15,0.85)
piec<-data.frame(title,type,value)
library(tidyverse)
p1<-ggplot(data = piec, aes(x = "", y = value, fill = type)) +
geom_bar(stat = "identity") +
geom_text(aes(label = value), position = position_stack(vjust = 0.5)) +
coord_polar(theta = "y")
#facet_grid(title ~ ., scales = "free")
p1
piec <- piec %>% group_by(title) %>% mutate(pos=cumsum(value)-0.5*value)
p2<-ggplot(data = piec) +
geom_bar(aes(x = "", y = value, fill = type), stat = "identity") +
geom_text(aes(x = "", y = pos, label = value)) +
coord_polar(theta = "y")
#facet_grid(Channel ~ ., scales = "free")
p2
You don't have to supply different y values for geom_text and geom_bar (use y = value for both of them). Next you have to specify position in geom_text. Finally, remove scales from facets.
library(ggplot2)
title<-c(1,1,2,2,3,3,4,4,5,5,6,6)
type<-c('A','B','A','B','A','B','A','B','A','B','A','B')
value<-c(0.25,0.75,0.3,0.7,0.4,0.6,0.5,0.5,0.1,0.9,0.15,0.85)
piec<-data.frame(title,type,value)
ggplot(piec, aes("", value, fill = type)) +
geom_bar(stat = "identity", color = "white", size = 1) +
geom_text(aes(label = paste0(value * 100, "%")),
position = position_stack(vjust = 0.5),
color = "white", size = 3) +
coord_polar(theta = "y") +
facet_wrap(~ title, ncol = 3) +
scale_fill_manual(values = c("#0048cc", "#cc8400")) +
theme_void()
This question already has an answer here:
Dual y axis (second axis) use in ggplot2
(1 answer)
Closed 5 years ago.
I know this topic has arisen some time in different threads of this page, but I am afraid that following the instructions of all of them I have not managed to fix it. I have been trying to solve this problem for a week that seems quite trivial and I can not find the way.
I do not know if it's about differences in the graphics or that there is something I do wrong. The case is as follows. I have two graphics using the ggplot2 package:
library(ggplot2)
data<-data.frame(Age=0,var2=0,var1=0,inf=0,sup=0,ppv=0)
data[1,]<-c(1,1,0.857,0.793,0.904,0.03)
data[2,]<-c(1,2,0.771 ,0.74,0.799,0.056)
data[3,]<-c(1,3,0.763 ,0.717,0.804,0.06)
data[4,]<-c(1,4,0.724 ,0.653,0.785,0.09)
data[5,]<-c(2,1,0.906,0.866,0.934,0.055)
data[6,]<-c(2,2,0.785 ,0.754,0.813,0.067)
data[7,]<-c(2,3,0.660,0.593,0.722,0.089)
data[8,]<-c(2,4,0.544,0.425,0.658,0.123)
pd <- position_dodge(0.2) #
names(data)<-c("Age","var2","var1","inf","sup","ppv")
data$Age<-as.character(data$Age)
data$var2<-as.character(data$var2)
p<- ggplot(data, aes(x=var2, y=var1, colour=Age)) +
geom_errorbar(aes(ymin=inf, ymax=sup), width=.1 , position=pd) +
geom_line(position=pd,aes(group=Age),linetype=c("dashed")) +
geom_point(position=pd,size=3) +
theme_light()+
ylim(0,1) +
scale_color_manual(values=c("1"="grey55","2"="grey15"))+guides(fill=guide_legend(nrow=2,byrow=TRUE)
)
s<- ggplot(data, aes(x=var2, y=ppv, colour=Age)) +
geom_line(position=pd,aes(group=Age),linetype=c("dashed")) +
geom_point(position=pd,size=3) +
theme_light()+
ylim(0,0.2) + scale_color_manual(values=c("1"="grey55","2"="grey15"))+guides(fill=guide_legend(nrow=2,byrow=TRUE)
)
They look like this:
Image of p
Image of s
I was wondering if someone would know the way to put them together in a single graph, with the two scales that they currently have, for example, the y axis of the graph p at the left side and the y axis of the graph s at the right side since I can not directly draw both data in a graph due to the radical difference in the scales .
Thank you very much for your time,
Best regards,
try this code, you should set aes at new layer.
ggplot(data, aes(x = var2, y = var1, colour=Age)) +
geom_errorbar(aes(ymin = inf, ymax = sup), width = .1, position = pd) +
geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
geom_point(position = pd, size = 3) +
geom_line(position = pd, aes(x = var2, y = ppv * 5, colour = Age, group = Age), linetype = c("dashed"), data = data) +
geom_point(aes(x = var2, y = ppv * 5, colour = Age, group = Age), position = pd, size = 5) +
theme_light() +
scale_color_manual(values = c("1" = "grey55", "2" = "grey15")) +
scale_y_continuous(sec.axis = sec_axis(~./5)) +
guides(fill = guide_legend(nrow = 2, byrow = TRUE))
dodged bar plot in ggplot again has me stumped. I asked about annotating text above bars on here a few weeks back (LINK) and got a terrific response to use + stat_bin(geom="text", aes(label=..count.., vjust=-1)). I figured since I already have the counts I'll just supply them with out the .. before and after and I told stat_bin that the position was dodge. It lines them up over the center of the group and adjusts up and down. Probably something minor. Please help me to get the text over the bars.
mtcars2 <- data.frame(type=factor(mtcars$cyl),
group=factor(mtcars$gear))
library(plyr); library(ggplot)
dat <- rbind(ddply(mtcars2,.(type,group), summarise,
count = length(group)),c(8,4,NA))
p2 <- ggplot(dat,aes(x = type,y = count,fill = group)) +
geom_bar(colour = "black",position = "dodge",stat = "identity") +
stat_bin(geom="text", aes(position='dodge', label=count, vjust=-.6))
I was having trouble getting the position dodges to line up, so I ended up creating a position_dodge object (is that the right terminology?), saving it to a variable, and then using that as the position for both geoms. Somewhat infuriatingly, they still seem to be a little off centre.
dodgewidth <- position_dodge(width=0.9)
ggplot(dat,aes(x = type,y = count, fill = group)) +
geom_bar(colour = "black", position = dodgewidth ,stat = "identity") +
stat_bin(geom="text", position= dodgewidth, aes(x=type, label=count), vjust=-1)
Updated geom_bar() needs stat = "identity"
I think this does what you want as well.
mtcars2 <- data.frame(type = factor(mtcars$cyl), group = factor(mtcars$gear))
library(plyr); library(ggplot2)
dat <- rbind(ddply(mtcars2, .(type, group), summarise, count = length(group)), c(8, 4, NA))
p2 <- ggplot(dat, aes(x = type,y = count,fill = group)) +
geom_bar(stat = "identity", colour = "black",position = "dodge", width = 0.8) +
ylim(0, 14) +
geom_text(aes(label = count, x = type, y = count), position = position_dodge(width = 0.8), vjust = -0.6)
p2