I am trying to make a combo chart using ggplot2. However i want to add a text box sort outside my plot body. I am unable to place it at the desired location
I have used grid pack to create grob and include that in annotation in the ggplot code. Additionally i have also put the same text in geom_text. How do i ensure the text comes say below the legend. Following is my code
m <- ggplot() +
geom_area(data= (ly_vol_ntwk %>%
mutate(Wk_end_d = as.factor(Wk_end_d))%>%
filter(!is.na(value_new))),
aes(x = Wk_end_d, y = value_new ,group = variable,fill=variable))+
geom_bar(data = (fcst_act_vol_ntwk %>%
mutate(Wk_end_d = as.factor(Wk_end_d))%>%
filter(!is.na(value_new))),
aes(x = Wk_end_d, y = value_new, group = variable, fill = variable),
stat = "identity",position = "dodge", width =0.5)+
geom_line(data = (var_vol_ntwk %>%
mutate(Wk_end_d = as.factor(Wk_end_d))%>%
filter(!is.na(value_new))),
aes(x = Wk_end_d, y = value_new,
group = variable, fill= variable), size = 0.8)+
scale_y_continuous(sec.axis = sec_axis(trans = ~./100000,
name = "Variance", breaks = waiver(),
labels=function(x) paste0(x,"%")))+
theme_set(theme_bw())+
theme(axis.text.x = element_text(angle=65, vjust=0.5,face = "plain"),
text = element_text(size=9), legend.position = "bottom", legend.title = element_blank())+
labs(title= "Inbound - Network", x= "Week end date", y = " ")+
scale_fill_manual(values = c("#C5E0B4","#7030A0", "#D9D9D9","#ED7D31","black"))+
geom_text(label = "LW Variance",
aes(x = 19, y = -1960000),
check_overlap = TRUE) #annotation_custom(grob = textGrob("LW Variance"), xmin = 18, xmax = 18, ymin = -1030000, ymax = -1030000)+ coord_cartesian(clip = 'off')
I need to get the text box with a border outside the area of the ggplot. Can you please help me?
You can place text below plot area with labs(caption = "text"), but you can't place captions on top of the plot. However, you could use subtitles labs(subtitle = "text") to produce a similar visual of captions on the top.
To further control the aspect of both options use theme(plot.caption = element_text(...), plot.subtitle = element_text(...)). Type ?element_text in your console to get all the options for text formatting.
For example:
library(ggplot2)
df <- data.frame(x = rnorm(50), y = rnorm(50))
ggplot(df, aes(x, y)) +
geom_point() +
labs(subtitle = "Your text here", caption = "Your text here") +
theme(plot.caption = element_text(colour = "red", hjust = 0, angle = 15),
plot.subtitle = element_text(size = 18, face = "bold", hjust = 0.8))
If you want it below your current legend, you can always add a dummy legend and put your text as its name. An example:
ggplot(mtcars, aes(mpg, wt, color = gear,fill = "a")) +
geom_point() +
scale_fill_discrete(name = "Your custom caption\ngoes here", labels = "") +
theme(legend.key = element_rect(fill = "white")) +
guides(color = guide_legend(order = 1),
fill = guide_legend(order = 2, override.aes = list(linetype = 0, shape=NA))) # setting the order parameter in guide_legend will help place it below your existing legend(s)
Related
I have horizontal dots plot replotted via ggplotly
df <- data.frame (origin = c("A","B","C","D","E","F","G","H","I","J"),
Percentage = c(23,16,32,71,3,60,15,21,44,60),
rate = c(10,12,20,200,-25,12,13,90,-105,23),
change = c(10,12,-5,12,6,8,0.5,-2,5,-2)
library(ggplot2)
plt <- ggplot(df, aes(x = rate, y = factor(origin, rev(origin)))) +
geom_hline(aes(yintercept = origin), color = 'gray') +
geom_vline(xintercept = 0, linetype = 2, color = 'gray') +
geom_point(aes(color = 'Rate'), size = 10) +
geom_text(aes(label = rate), color = 'white') +
geom_point(aes(x = change, color = 'Change'), size = 10) +
geom_text(aes(label = change, x = change)) +
theme_minimal(base_size = 16) +
scale_x_continuous(labels = ~paste0(.x, '%'), name = NULL) +
scale_color_manual(values = c('#aac7c4', '#5f9299')) +
theme(panel.grid = element_blank(),
axis.text.y = element_text(color = 'gray50')) +
labs(color = NULL, y = NULL)
ggplotly(plt)
The only issue is that when I hide one of the dot from the figure, texts are still appeared (see below), so is there way to tackle this issue and hide text with circle by clicking on legend?
P.S
(setting text colour in white color = 'white' is not option for me)
You can use the fill aesthetic for the points (as long as they are shape = 21) and use the color aesthetic for the text. As long as these have the same labels for aesthetic mapping, the interactivity for both points and text will be linked.
One minor annoyance is that this changes the plotly legend labels, even though they are correct in the ggplot version. This requires a little direct manipulation of the plotly object itself:
plt <- ggplot(df, aes(x = rate, y = factor(origin, rev(origin)))) +
geom_segment(aes(x = -100, xend = 200,
y = origin, yend = origin), color = 'gray') +
geom_vline(xintercept = 0, linetype = 2, color = 'gray') +
geom_point(aes(fill = 'Rate'), shape = 21, size = 10, color = NA) +
geom_text(aes(label = rate, color = 'Rate')) +
geom_point(aes(x = change, fill = 'Change'),
color = NA, shape = 21, size = 10) +
geom_text(aes(label = change, x = change, color = "Change")) +
theme_minimal(base_size = 16) +
scale_x_continuous(labels = ~paste0(.x, '%'), name = NULL) +
scale_fill_manual(values = c('#aac7c4', '#5f9299')) +
scale_color_manual(values = c("black", "white")) +
theme(panel.grid = element_blank(),
axis.text.y = element_text(color = 'gray50')) +
labs(color = NULL, y = NULL, fill = NULL)
p <- ggplotly(plt)
p$x$data[[3]]$name <- p$x$data[[3]]$legendgroup <-
p$x$data[[4]]$name <- p$x$data[[4]]$legendgroup <- "Rate"
p$x$data[[5]]$name <- p$x$data[[5]]$legendgroup <-
p$x$data[[6]]$name <- p$x$data[[6]]$legendgroup <- "Change"
p
This gives us the following plot:
Now clicking on Rate we get:
And clicking on Change we get
I am plotting a smooth to my data using geom_smooth and using geom_ribbon to plot shaded confidence intervals for this smooth. No matter what I try I cannot get a single legend that represents both the smooth and the ribbon correctly, i.e I am wanting a single legend that has the correct colours and labels for both the smooth and the ribbon. I have tried using + guides(fill = FALSE), guides(colour = FALSE), I also read that giving both colour and fill the same label inside labs() should produce a single unified legend.
Any help would be much appreciated.
Note that I have also tried to reset the legend labels and colours using scale_colour_manual()
The below code produces the below figure. Note that there are two curves here that are essentially overlapping. The relabelling and setting couours has worked for the geom_smooth legend but not the geom_ribbon legend and I still have two legends showing which is not what I want.
ggplot(pred.dat, aes(x = age.x, y = fit, colour = tagged)) +
geom_smooth(size = 1.2) +
geom_ribbon(aes(ymin = lci, ymax = uci, fill = tagged), alpha = 0.2, colour = NA) +
theme_classic() +
labs(x = "Age (days since hatch)", y = "Body mass (g)", colour = "", fill = "") +
scale_colour_manual(labels = c("Untagged", "Tagged"), values = c("#3399FF", "#FF0033")) +
theme(axis.title.x = element_text(face = "bold", size = 14),
axis.title.y = element_text(face = "bold", size = 14),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.text = element_text(size = 12))
The problem is that you provide new labels for the color-aesthetic but not for the fill-aesthetic. Consequently ggplot shows two legends because the labels are different.
You can either also provide the same labels for the fill-aesthetic (code option #1 below) or you can set the labels for the levels of your grouping variable ("tagged") before calling ggplot (code option #2).
library(ggplot2)
#make some data
x = seq(0,2*pi, by = 0.01)
pred.dat <- data.frame(x = c(x,x),
y = c(sin(x), cos(x)) + rnorm(length(x) * 2, 0, 1),
tag = rep(0:1, each = length(x)))
pred.dat$lci <- c(sin(x), cos(x)) - 0.4
pred.dat$uci <- c(sin(x), cos(x)) + 0.4
#option 1: set labels within ggplot call
pred.dat$tagged <- as.factor(pred.dat$tag)
ggplot(pred.dat, aes(x = x, y = y, color = tagged, fill = tagged)) +
geom_smooth(size = 1.2) +
geom_ribbon(aes(ymin = lci, ymax = uci), alpha = 0.2, color = NA) +
scale_color_manual(labels = c("untagged", "tagged"), values = c("#F8766D", "#00BFC4")) +
scale_fill_manual(labels = c("untagged", "tagged"), values = c("#F8766D", "#00BFC4")) +
theme_classic() + theme(legend.title = element_blank())
#option 2: set labels before ggplot call
pred.dat$tagged <- factor(pred.dat$tag, levels = 0:1, labels = c("untagged", "tagged"))
ggplot(pred.dat, aes(x = x, y = y, color = tagged, fill = tagged)) +
geom_smooth(size = 1.2) +
geom_ribbon(aes(ymin = lci, ymax = uci), alpha = 0.2, color = NA) +
theme_classic() + theme(legend.title = element_blank())
I cannot seem to change the legend title without the legend splitting my shape and color into two separate legends. How can i change the combined legend title? The image is what the graph looks like.
ggplot(data = df, aes (x = factor(dminp,c("-3 to -1", "-1 to 1")), y = sum_diff,col = factor(dmin), shape = factor(dmin), group = factor(dmin)))+
xlab("Range of Difficulty Parameters for Screen Items") + ylab("Bias Due to Skip-Logic") +
stat_summary(geom = "point",fun.y = "mean",size = 8, aes(shape = factor(dmin)))+
stat_summary(geom = "point",fun.y = "mean",size = 8, aes(col = factor(dmin)))+
scale_shape_manual(values = c(8,5)) + theme_bw() + scale_colour_manual(values = c("orange","purple"))+
theme(panel.grid.major.x = element_blank(),
panel.grid.major = element_line(colour = "black",size=0.25))+ theme(legend.justification = "top")
I have tried using labs(col = "what i want it to be named") but this adds a 2nd legend and splits shape/color.
How about trying:
... +
scale_shape_manual(name="X",values = c(8,5)) +
scale_colour_manual(name="X",values = c("orange","purple"))+
..
Here's an example:
ggplot(iris,aes(x=Sepal.Width,y=Sepal.Length,shape=Species,col=Species)) +
geom_point()+
scale_color_manual(name="X",values=c("Blue","Orange","Red")) +
scale_shape_manual(name="X",values=c(17,18,19))
I have the following dataframe in R
DF_1<-data.frame("ID"=c("A_1", "A_2"), 'Sum'= c(2500,12500), "RR"=
c(95,95), "CC"= c(50,50), "nn"=c(4,4), "DP"= c(12.5,100))
I have created the following barplot with text written in the barplot as follows
p2<-ggplot(data = DF_1, mapping = aes(x = ID, y = DP,
fill=str_wrap(ID,10))) + geom_bar(stat = 'identity', width = .35, position
= "dodge")+ geom_text(aes(label=RR) , position = position_dodge(0.9),vjust
= 2,check_overlap = TRUE)+geom_text(aes(label=CC) , position = postion_dodge(0.9),vjust = 4,check_overlap = TRUE)+ geom_text(aes(label=nn) , position = position_dodge(0.9),vjust = 6,check_overlap = TRUE)+ labs(fill = "LEGEND")+labs(x = "XLabels", y= "DPP")+theme(legend.key.height = unit( 2 ,"cm"))+theme(axis.text.x=element_blank())+ggtitle("DPPCHART")+ theme(plot.title = element_text(hjust = 0.5))
In the plot so generated the three text labels are generated clearly on the barplot. The next step is to make dynamic ticks work
p<-ggplotly(p, dynamicticks=T)
Now the three text labels overlap each other.
Is there a way to retain the text labels separately when using ggplotly.
You can use HTML directly inside the labels like this to remove the overlap:
library(stringr)
library(ggplot2)
library(plotly)
DF_1 <- data.frame("ID"=c("A_1", "A_2"), 'Sum'= c(2500,12500),
"RR"= c(95,95), "CC"= c(50,50), "nn"=c(4,4), "DP"= c(12.5,100))
p <- ggplot(data = DF_1, mapping = aes(x = ID, y = DP,fill=str_wrap(ID,10))) +
geom_bar(stat = 'identity', width = .35, position = "dodge") +
geom_text(aes(label=paste0(RR, "<br>", CC, "<br>", nn)) ,
position = position_dodge(0.9), vjust = 2, check_overlap = TRUE) +
labs(fill = "LEGEND") + labs(x = "XLabels", y= "DPP") +
theme(legend.key.height = unit( 2 ,"cm")) +
theme(axis.text.x=element_blank()) +
ggtitle("DPPCHART") +
theme(plot.title = element_text(hjust = 0.5)) +
scale_y_continuous(limits = c(0,110))
ggplotly(p) # can use with or without dynamicTicks=TRUE
Output is:
df.test <- data.frame(val=c(0.55,0.42,-0.05),name=letters[1:3],
desc='This is the description of values'
p <- ggplot(df.test, aes(name, val, label = desc)) +
geom_bar(stat = "identity", col = 'black', fill = 'lightgreen') +
labs(title = "Test", x = " ", y = "value", fill = "") +
theme_bw() +
guides(fill = FALSE)
p + geom_text(angle = 90, size = 8, hjust = 1.25, position = position_dodge(width = 0.9))
This generates the following plot:
I want to align the text and force the it to start at the beginning of each chart, so that all of them can be visible (it is ok if it falls outside the small chart). How can I achieve this?
Is this what you're looking for?
p <- ggplot(df.test,aes(name,val,label=desc))+
geom_bar(stat="identity",col='black',fill='lightgreen')+
labs(title = "Test", x = " ", y = "value",fill = "")+
theme_bw()+
guides(fill=FALSE)
p+geom_text(angle=90,size=8,hjust=0,aes(x=name,y=rep(0,nrow(df.test)),label=desc),inherit.aes=F)