Create A Custom Static Label Above Legend in R with GGPlot - r

I have found a lot of information regarding either changing a ggplot label or adding text to the plot itself. However, I want to add text above the legend. We currently use Python to do some data manipulation and then plot it using R. Our python file outputs the data needed by the plot as well as another text file containing the settings. I want to add these settings to the plot, preferably in a box above the legend. I am confident that I can figure out how to input the text file with the settings so I need to know is how to add, for example, "Settings Test" above the legend. We are using ggplot and I have no issue either changing the legend text or adding text to the plot area (the grey area) but I have not been able to find much on adding custom static text above the legend.
Thank you.
Here is an image that I reference
Here is the code that I have tried as suggested but the output graph did not change.
p <- ggplot(MAE_AUC, aes(x=mae, y=auc, color=file), environment()) + geom_point(
aes(size=count))
p2 <- p + geom_smooth(method=lm, fullrange=TRUE) +
theme(panel.background=element_rect(fill='white', colour='black')) +
theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank()) +
scale_colour_discrete(label=filenames)
p2$labels$fill
p2 + labs(fill=paste("StackOverflow", p2$labels$fill, sep="\n"))

Here's one way to do this - basically just concatenating the contents of from labels$fill -- look at str(p) for more information.
library(ggplot2)
p <- ggplot(PlantGrowth, aes(x=group, y=weight, fill=group)) + geom_boxplot()
p$labels$fill
# [1] "group"
# If you just want to change the label to "test"
# p +
# labs(fill = "test")
p +
labs(fill = paste("StackOverflow", p$labels$fill, sep = "\n"))
Or you could make this more dynamic with:
my_static_label <- c("StackOverflow")
p +
labs(fill = paste(my_static_label, p$labels$fill, sep = "\n"))

Related

How to place legend inside caption area on R

I am using R studio / R Markdown to create plots, some with ggplot, some with base R function. I would like to insert a caption for each of my plots which contains the legend similar to the example shown here:
Can anyone suggest how to place the legend of my plots (built with ggplot and base R functions) within the caption as shown in this example?
I searched online and found out that it is possible to use something like:
p + labs(caption="Figure S1: This is the Figure Legend")
however, I could not find how to embed the legend into the caption, and I also could not find a solution for plots made using base R.
There are some solutions that require Latex, but I cannot use Latex for this project.
You could just push the legend to the bottom and add a custom title - inlcude a counter to get numbered Plots:
library(ggplot2)
# using the internal iris dataset
iris
# set counter to zero
NR <- 0
# Add counter and build plot
NR <- NR + 1
legend <- paste0("Fig. ", NR, ": This is a Plot about...:")
ggplot2::ggplot(iris, aes(Sepal.Length, Petal.Width, color = Species)) +
ggplot2::geom_point() +
ggplot2::labs(color= legend) +
ggplot2::theme(legend.position = "bottom")
# Add counter and build second plot
NR <- NR + 1
legend <- paste0("Fig. ", NR , ": This is a Plot about...:")
ggplot2::ggplot(iris, aes(Sepal.Width, Petal.Length, color = Species)) +
ggplot2::geom_point() +
ggplot2::labs(color= legend) +
ggplot2::theme(legend.position = "bottom")

unable to wrap text in y axis title on R Shiny using ggplot

I'm trying to plot a graph in r shiny, where the values for x-axis and y-axis come from dropdown.
On y-axis, the title is very huge and i need to wrap it. But none of the wrap function is working.
y-axis title = thistextisnumerator/thistextisdenominator, this needs to displayed, but i'm unable to wrap it
**Possible y-axis titles:**
y-axis title = this text is very very long
y-axis title = this text is very long (and very large) hence going outside the plot
code:
ggplot(data=fin, aes(x = color_var, y = ratio,fill=color_var))+
geom_boxplot()+
geom_point(aes(text = paste0(paste0("number: ",number),
paste0("<br>",isolate(input$Y),": ",round(ratio,2))))) +
theme_grey(base_size=10)+
ylim(min(fin$ratio),max(fin$ratio))+
labs(title =paste0("Box Plot ",' '),y=(paste0(isolate(input$X)," / ",isolate(input$Y))),x=x_value) +
theme(axis.text.y = element_text(size=1),axis.title.y = element_text(size=1)) +
guides(fill=guide_legend(title=x_value_legend))
You did not provide any data to help us help you so I'm building a dummy graph with the database mtcars. Let's see if this helps you:
#building dummy graph p
library(ggplot2)
p <- ggplot(mtcars,aes(x=wt,y=mpg))+geom_point()
Now insofar as you seem to want your text in a mathematical annotation, I'd suggest to use the function expression():
p + labs(y = expression(frac("thistextisnumerator", "thistextisdenominator")))
Which will result into the following graph:
If you do not want the line, you can use either one of the following codes:
p + labs(y = expression(atop("thistextisnumerator", "thistextisdenominator")))
p + labs(y = expression(over("thistextisnumerator", "thistextisdenominator")))
Or even easier:
p + labs(y = paste0("thistextisnumerator", "\n", "thistextisdenominator"))
Where \n is the character for line break.

Plot three-variable line chart

I need to plot a line chart that contains 2 lines, as per the dataset below:
I need each line of the chart to match the Technique. The values of X and Y are Release and Added respectively. The graph I need to generate is similar to the one in the figure below:
To plot the first line, I tried:
plot(IrisChangeModules[IrisChangeModules$Technique=="aop"]$Added, IrisChangeModules[IrisChangeModules$Technique=="aop"]$Release, type = "l")
Using ggplot (not a base r solution though), one way of getting your desired output can be:
library(ggplot2)
ggplot(dataset, aes(x=Release, y=Added, group=Technique)) + geom_line(aes(linetype = Technique, color=Technique)) + geom_point(aes(color = Technique)) + theme_bw()
The output given your dummy data looks:
You can play with the different parameters of ggplot to position the legend and other aspects of the plot.
UPDATE:
Remove ylab("Added Modules") + scale_color_discrete(name = "SPL Techniques") from your script and save the output on a variable as follows:
x <- ggplot(IrisChangeModules, aes(x=Release, y=Added, group=Technique)) + geom_line(aes(linetype = Technique, color=Technique)) + geom_point(aes(color = Technique)) + theme_bw()
Then overlay your modified label and new legend title as:
x+ labs(y = "Added Modules") + scale_fill_discrete(name = "SPL Techniques")
That'll give you what you want.
Firstly create an ordered release int
IrisChangeModules$release_n = 1:nrow(IrisChangeModules)
Now create a blank plot, type="n" means nothing is actually plotted.
plot(Added~release_n,data=IrisChangeModules,type="n",xaxt = "n")
Create axis labels with the original variable ( you may need to update the at if you have more than 4 releases).
axis(1,at=1:4,labels=IrisChangeModules$Release)
Add lines are required
lines(Added~release_n,data=IrisChangeModules[IrisChangeModules$tech=="dop",],type='l',col="green")
lines(Added~release_n,data=IrisChangeModules[IrisChangeModules$tech=="aop",],type='l',col="red")
Add a legend, make sure you are updating if you add more lines
legend(1,90,
legend=c("dop", "aop"),
col=c("green", "red"),
lty=1,
cex=0.8)

Printing an empty ggplot with a legend

I'm trying to print an empty ggplot, but still include a legend/scale and I'm running into problems.
Here's the relevant section of the code:
p <- ggplot(data=df, aes(x=factor(year_id), y=location_name)) +
geom_point(aes(size=count.sum), na.rm=F) +
#geom_blank() +
theme_bw() +
theme(axis.text.x=element_text(angle=50, hjust=1)) +
labs(x="Year", y="") +
scale_size(name="Site-years of data", range=c(min(breaks),max(breaks)), breaks=breaks) +
ggtitle(paste0(cause_name, ", Data Availability")) +
facet_wrap(~type)
plots[[i]] <- p
Breaks is just the vector 1,2 and the column count.sum is all NA.
What I want is to print out the chart, which has no data in it (no points), but still have a legend with a small dot representing 1 and a bigger dot representing 2.
As it is right now, I get the error "Discrete value supplied to continuous scale".
If I use geom_blank instead of geom_point, the chart successfully gets created and is empty, but there's no legend,
How can I get both the empty chart and a legend?
Thanks
you could zoom somewhere outside the range of the data, ggplot(data.frame(x=1:10), aes(x,x,size=x)) + geom_point() + coord_cartesian(xlim=c(20,30))

Add a footnote citation outside of plot area in R?

I'd like to add a footnote citation to my 3-panel facet grid plot produced in R. It's a footnote to credit the data source. I'd ideally like to have it below and external to all three axes---preferably in the lower left.
I'm using ggplot2 and also ggsave(). This means I can't use grid.text()-based solutions, because that only draws on the x11() window, and can't be added to the ggplot object.
Using instead png() ...code... dev.off() does not appear to be an option because I need ggsave's resizing parameters, and find this command produces better, clearer prints (that are also much faster, because I'm not printing to the screen).
Here's my basic code:
p1 <- ggplot(data, aes(date, value))
facet_grid(variable ~ .) + geom_point(aes(y =value), size=1) +
theme_bw() +
opts(title=mytitle)
print(p1)
ggsave("FILE.png",width=mywidth, height=myheight, p1, dpi=90)
I've tried:
p1 <- ggplot(data, aes(date, value))
facet_grid(variable ~ .) + geom_point(aes(y =value), size=1) +
theme_bw() +
opts(title=mytitle)
print(p1)
grid.text(unit(0.1,"npc"),0.025,label = "Data courtesy of Me")
grid.gedit("GRID.text", gp=gpar(fontsize=7))
ggsave("FILE.png",width=mywidth, height=myheight, p1, dpi=90)
This appropriately puts the footnote in the lower left corner on the x11() display, external to the plots, but unfortunately, since it isn't applied to the p1 object, it isn't saved by the ggsave command.
I've also tried:
p1 <- ggplot(data, aes(date, value))
facet_grid(variable ~ .) + geom_point(aes(y =value), size=1) +
theme_bw() +
opts(title=mytitle) +
annotate("text", label = "Footnote", x = 0, y = 10, size = 5, colour = "black") +
print(p1)
ggsave("FILE.png",width=mywidth, height=myheight, p1, dpi=90)
This successfully prints using ggsave, however it has the following problems:
It is repeated 3 times, in each of the 3 facets, rather than 1 time.
It is contained within the plots, rather than external to them.
Text is difficult to place---seems to be using plot units (my x-axis is date, so 0 puts it around 1970).
The text size doesn't seem to change despite my size parameter.
A couple of related links from when I explored this...
ggplot2 footnote
(doesn't work with ggsave)
How to label the barplot in ggplot with the labels in another test result?
(is inside the plot, not external/below plot)
Different font faces and sizes within label text entries in ggplot2
(doesn't work with ggsave)
problem saving pdf file in R with ggplot2
ggplot2 now has this ability natively with no need for additional packages. ... + labs(caption = "footnote", ...)
library(ggplot2)
ggplot(diamonds, aes(carat, price, color = clarity)) +
geom_point() +
labs(title = "Diamonds are forever...",
subtitle = "Carat weight by Price",
caption = "H. Wickham. ggplot2: Elegant Graphics for Data Analysis Springer-Verlag New York, 2009.")
library(gridExtra)
library(grid)
library(ggplot2)
g <- grid.arrange(qplot(1:10, 1:10, colour=1:10) + labs(caption="ggplot2 caption"),
bottom = textGrob("grid caption", x = 1,
hjust = 1, gp = gpar(fontface = 3L, fontsize = 9)))
ggsave("plot.pdf", g)
Edit: note that this solution is somewhat complementary to the recent caption argument added to ggplot2, since the textGrob can here be aligned with respect to the whole figure, not just the plot panel.
Adding to the answer of Brandon Bertelsen: if you want to have the caption in the left corner, add
theme(plot.caption = element_text(hjust = 0))

Resources