How to use superscript in geom_text? - r

I am trying to use superscript in geom_text. But I am unable to do that. I am using the following code
library(caret)
library(tidyverse)
summ <- iris %>%
group_by(Species) %>%
summarise(R = cor(Sepal.Length, Petal.Length, use="pairwise.complete.obs"),
RMSE = RMSE(Sepal.Length, Petal.Length)) %>%
mutate_if(is.numeric, round, digits=2)
p <- ggplot(data=iris, aes(x = Sepal.Length, y = Petal.Length)) +
geom_point(color="blue",alpha = 1/3) +
facet_wrap(Species ~ ., scales="free") +
geom_smooth(method=lm, fill="black", formula = y ~ x) +
xlab("Sepal Length") +
ylab("Petal Length") + theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
# Here we create our annotations data frame.
df.annotations <- data.frame()
# R
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("R", summ$R,
sep = " = ")))
# RMSE
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("RMSE", summ$RMSE,
sep = " = ")))
# This here is important, especially naming the first column
# Species
colnames(df.annotations) <- c("Species", "label")
vertical_adjustment = ifelse(grepl("\\bR\\b",df.annotations$label), 1.5, 3)
p + geom_text(data = df.annotations, aes(x=-Inf, y=+Inf, label=label),
hjust = -0.1, vjust = vertical_adjustment, size=3.5)
My expected output is
How can I add the unit for RMSE after the value and superscript 2 after R i.e. R^2? You can also see that there is a slight shift in the alignment of RMSE with respect to R. How can I make them into the same line?

This could be achieved like so:
Set parse=TRUE in geom_text
Make use of ?plotmath to add superscripts to your labels
# Here we create our annotations data frame.
df.annotations <- data.frame(
Species = rep(summ$Species, 2),
label = c(
paste0("~R^{2} == ", summ$R),
paste0("~RMSE == ", summ$RMSE, "~m^{3} ~m^{-3}")
)
)
vertical_adjustment = ifelse(grepl("\\bR\\b", df.annotations$label), 1.5, 3)
p + geom_text(data = df.annotations, aes(x=-Inf, y=+Inf, label=label),
hjust = 0, vjust = vertical_adjustment, size=3.5, parse = TRUE)

Another approach is to use the ggtext package, which enables markdown formatting in ggplot text objects. I find this syntax much easier to use than R's plotmath, especially for things like italics and color:
df.annotations <- data.frame(
Species = rep(summ$Species, 2),
label = c(
paste0("R<sup>2</sup> = ", summ$R),
paste0("RMSE = ", summ$RMSE, "m<sup>3</sup> m<sup>-3</sup>")
)
)
vertical_adjustment = ifelse(grepl("\\bR\\b", df.annotations$label), 1.5, 2.5)
p + geom_richtext(data = df.annotations, aes(x=-Inf, y=+Inf, label=label),
hjust = 0, vjust = vertical_adjustment, size=3.5, label.size = 0)

Related

How to automatically position multiple model evaluation parameters in facetted ggplot2?

I am trying to automatically position multiple model evaluation parameters in facetted ggplot. This answer has helped me to put the R2 and RMSE in facetted ggplot automatically using the following code
library(caret)
library(tidyverse)
summ <- iris %>%
group_by(Species) %>%
summarise(Rsq = R2(Sepal.Length, Petal.Length),
RMSE = RMSE(Sepal.Length, Petal.Length)) %>%
mutate_if(is.numeric, round, digits=2)
p <- ggplot(data=iris, aes(x = Sepal.Length, y = Petal.Length)) +
geom_point(color="blue",alpha = 1/3) +
facet_wrap(Species ~ ., scales="free") +
geom_smooth(method=lm, fill="black", formula = y ~ x) +
xlab("Sepal Length") +
ylab("Petal Length") + theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
# Here we create our annotations data frame.
df.annotations <- data.frame()
# Rsq
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("Rsq", summ$Rsq,
sep = " = ")))
# RMSE
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("RMSE", summ$RMSE,
sep = " = ")))
# This here is important, especially naming the first column
# Species
colnames(df.annotations) <- c("Species", "label")
vertical_adjustment = ifelse(grepl("Rsq",df.annotations$label),1.5,3)
p + geom_text(data=df.annotations,aes(x=-Inf,y=+Inf,label=label),
hjust = -0.1, vjust = vertical_adjustment, size=3.5)
I have calculated NSE using hydroGOF package like
library(hydroGOF)
summ <- iris %>%
group_by(Species) %>%
summarise(Rsq = R2(Sepal.Length, Petal.Length),
RMSE = RMSE(Sepal.Length, Petal.Length),
NSE = NSE(Sepal.Length, Petal.Length)) %>%
mutate_if(is.numeric, round, digits=2)
Added the NSE to the df.annotations dataframe like
# NSE
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("NSE", summ$NSE,
sep = " = ")))
Now, how can I place multiple model evaluation parameters in facetted ggplot2?
This is the new part using case_when from dplyr package for aligning vertically:
library(dplyr)
vertical_adjustment = case_when(grepl("Rsq",df.annotations$label) ~ 1.5,
grepl("RMSE",df.annotations$label) ~ 3,
grepl("NSE",df.annotations$label) ~ 4.5)
p + geom_text(data=df.annotations,aes(x=-Inf,y=+Inf,label=label),
hjust = -0.1, vjust = vertical_adjustment, size=3.5)
The whole code:
library(caret)
library(tidyverse)
library(hydroGOF)
summ <- iris %>%
group_by(Species) %>%
summarise(Rsq = R2(Sepal.Length, Petal.Length),
RMSE = RMSE(Sepal.Length, Petal.Length),
NSE = NSE(Sepal.Length, Petal.Length)) %>%
mutate_if(is.numeric, round, digits=2)
p <- ggplot(data=iris, aes(x = Sepal.Length, y = Petal.Length)) +
geom_point(color="blue",alpha = 1/3) +
facet_wrap(Species ~ ., scales="free") +
geom_smooth(method=lm, fill="black", formula = y ~ x) +
xlab("Sepal Length") +
ylab("Petal Length") + theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
p
# Here we create our annotations data frame.
df.annotations <- data.frame()
# Rsq
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("Rsq", summ$Rsq,
sep = " = ")))
# RMSE
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("RMSE", summ$RMSE,
sep = " = ")))
df.annotations <- rbind(df.annotations,
cbind(as.character(summ$Species),
paste("NSE", summ$NSE,
sep = " = ")))
# This here is important, especially naming the first column
# Species
colnames(df.annotations) <- c("Species", "label")
library(dplyr)
vertical_adjustment = case_when(grepl("Rsq",df.annotations$label) ~ 1.5,
grepl("RMSE",df.annotations$label) ~ 3,
grepl("NSE",df.annotations$label) ~ 4.5)
p + geom_text(data=df.annotations,aes(x=-Inf,y=+Inf,label=label),
hjust = -0.1, vjust = vertical_adjustment, size=3.5)

How to colour code a PCA plot based on the data frame cell names?

data.matrix <- matrix(nrow=100, ncol=10)
colnames(data.matrix) <- c(
paste("wt", 1:5, sep=""),
paste("ko", 1:5, sep=""))
rownames(data.matrix) <- paste("gene", 1:100, sep="")
for (i in 1:100) {
wt.values <- rpois(5, lambda=sample(x=10:1000, size=1))
ko.values <- rpois(5, lambda=sample(x=10:1000, size=1))
data.matrix[i,] <- c(wt.values, ko.values)
}
head(data.matrix)
dim(data.matrix)
pca <- prcomp(t(data.matrix), scale=TRUE)
intall.packages("ggplot2")
library(ggplot2)
pca.data <- data.frame(Sample=rownames(pca$x),
X=pca$x[,1],
Y=pca$x[,2])
pca.data
ggplot(data=pca.data, aes(x=X, y=Y, label=Sample)) +
geom_text() +
xlab(paste("PC1 - ", pca.var.per[1], "%", sep="")) +
ylab(paste("PC2 - ", pca.var.per[2], "%", sep="")) +
theme_bw() +
ggtitle("My PCA Graph")
The above code gives me this final pca plot:
How can change the wt and ko points into coloured dots? (ie. change all "wt" points to blue dots and all "ko" points to red dots)
EDIT: The question was changed after my initial answer, see the bottom for updated answer.
You can get the second character of Sample with substr(), and then pass that to col. Here is an example:
library(ggplot2)
library(dplyr)
example_data <- data.frame(
Sample = c("A1.1", "H2.1", "F2.1", "B1.1", "C1.1", "S2.1", "J2.1", "K1.1"),
X = rnorm(n = 8),
Y = rnorm(n = 8)
)
example_data %>%
mutate(prop = substr(Sample, 2, 2)) %>% # Make a new column with the values
ggplot(aes(x = X, y = Y, label = Sample, col = prop)) +
geom_text() +
xlab(paste("PC1 - ")) +
xlab(paste("PC2 - ")) +
scale_color_manual(values = c("1" = "blue", "2" = "red")) + # Assigns colour to values
theme_bw() +
theme(legend.position = "none") # Removes legend
Created on 2021-06-07 by the reprex package (v0.3.0)
With the edited question, here is how to get points instead of text. Simply swap out geom_text() for geom_point().
example_data %>%
mutate(prop = substr(Sample, 2, 2)) %>% # This is where the magic happens
ggplot(aes(x = X, y = Y, label = Sample, col = prop)) +
# geom_text() +
geom_point() + # Will add points
xlab(paste("PC1 - ")) +
ylab(paste("PC2 - ")) +
scale_color_manual(values = c("1" = "blue", "2" = "red")) +
theme_bw() +
theme(legend.position = "none")
Created on 2021-06-07 by the reprex package (v0.3.0)

Add a vector of labels to multiple plots in ggplot [duplicate]

I want to annotate some text on last facet of the plot with the following code:
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ cyl)
p <- p + annotate("text", label = "Test", size = 4, x = 15, y = 5)
print(p)
But this code annotates the text on every facet. How can I get the annotated text on only one facet?
Function annotate() adds the same label to all panels in a plot with facets. If the intention is to add different annotations to each panel, or annotations to only some panels, a geometry has to be used instead of annotate(). To use a geometry, such as geom_text() we need to assemble a data frame containing the text of the labels in one column and columns for the variables to be mapped to other aesthetics, as well as the variable(s) used for faceting.
Typically you'd do something like this:
ann_text <- data.frame(mpg = 15,wt = 5,lab = "Text",
cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text")
It should work without specifying the factor variable completely, but will probably throw some warnings:
Function annotate() adds the same label to all panels in a plot with facets. If the intention is to add different annotations to each panel, or annotations to only some panels, a geometry has to be used instead of annotate(). To use a geometry, such as geom_text() we need to assemble a data frame containing the text of the labels in one column and columns for the variables to be mapped to other aesthetics, as well as the variable(s) used for faceting. This answer exemplifies this for both facet_wrap() and facet_grid().
Here's the plot without text annotations:
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
facet_grid(. ~ cyl) +
theme(panel.spacing = unit(1, "lines"))
p
Let's create an additional data frame to hold the text annotations:
dat_text <- data.frame(
label = c("4 cylinders", "6 cylinders", "8 cylinders"),
cyl = c(4, 6, 8)
)
p + geom_text(
data = dat_text,
mapping = aes(x = -Inf, y = -Inf, label = label),
hjust = -0.1,
vjust = -1
)
Alternatively, we can manually specify the position of each label:
dat_text <- data.frame(
label = c("4 cylinders", "6 cylinders", "8 cylinders"),
cyl = c(4, 6, 8),
x = c(20, 27.5, 25),
y = c(4, 4, 4.5)
)
p + geom_text(
data = dat_text,
mapping = aes(x = x, y = y, label = label)
)
We can also label plots across two facets:
dat_text <- data.frame(
cyl = c(4, 6, 8, 4, 6, 8),
am = c(0, 0, 0, 1, 1, 1)
)
dat_text$label <- sprintf(
"%s, %s cylinders",
ifelse(dat_text$am == 0, "automatic", "manual"),
dat_text$cyl
)
p +
facet_grid(am ~ cyl) +
geom_text(
size = 5,
data = dat_text,
mapping = aes(x = Inf, y = Inf, label = label),
hjust = 1.05,
vjust = 1.5
)
Notes:
You can use -Inf and Inf to position text at the edges of a panel.
You can use hjust and vjust to adjust the text justification.
The text label data frame dat_text should have a column that works with your facet_grid() or facet_wrap().
If anyone is looking for an easy way to label facets for reports or publications, the egg (CRAN) package has pretty nifty tag_facet() & tag_facet_outside() functions.
library(ggplot2)
p <- ggplot(mtcars, aes(qsec, mpg)) +
geom_point() +
facet_grid(. ~ am) +
theme_bw(base_size = 12)
# install.packages('egg', dependencies = TRUE)
library(egg)
Tag inside
Default
tag_facet(p)
Note: if you want to keep the strip text and background, try adding strip.text and strip.background back in theme or remove theme(strip.text = element_blank(), strip.background = element_blank()) from the original tag_facet() function.
tag_facet <- function(p, open = "(", close = ")", tag_pool = letters, x = -Inf, y = Inf,
hjust = -0.5, vjust = 1.5, fontface = 2, family = "", ...) {
gb <- ggplot_build(p)
lay <- gb$layout$layout
tags <- cbind(lay, label = paste0(open, tag_pool[lay$PANEL], close), x = x, y = y)
p + geom_text(data = tags, aes_string(x = "x", y = "y", label = "label"), ..., hjust = hjust,
vjust = vjust, fontface = fontface, family = family, inherit.aes = FALSE)
}
Align top right & use Roman numerals
tag_facet(p, x = Inf, y = Inf,
hjust = 1.5,
tag_pool = as.roman(1:nlevels(factor(mtcars$am))))
Align bottom left & use capital letters
tag_facet(p,
x = -Inf, y = -Inf,
vjust = -1,
open = "", close = ")",
tag_pool = LETTERS)
Define your own tags
my_tag <- c("i) 4 cylinders", "ii) 6 cyls")
tag_facet(p,
x = -Inf, y = -Inf,
vjust = -1, hjust = -0.25,
open = "", close = "",
fontface = 4,
size = 5,
family = "serif",
tag_pool = my_tag)
Tag outside
p2 <- ggplot(mtcars, aes(qsec, mpg)) +
geom_point() +
facet_grid(cyl ~ am, switch = 'y') +
theme_bw(base_size = 12) +
theme(strip.placement = 'outside')
tag_facet_outside(p2)
Edit: adding another alternative using the stickylabeller package
- `.n` numbers the facets numerically: `"1"`, `"2"`, `"3"`...
- `.l` numbers the facets using lowercase letters: `"a"`, `"b"`, `"c"`...
- `.L` numbers the facets using uppercase letters: `"A"`, `"B"`, `"C"`...
- `.r` numbers the facets using lowercase Roman numerals: `"i"`, `"ii"`, `"iii"`...
- `.R` numbers the facets using uppercase Roman numerals: `"I"`, `"II"`, `"III"`...
# devtools::install_github("rensa/stickylabeller")
library(stickylabeller)
ggplot(mtcars, aes(qsec, mpg)) +
geom_point() +
facet_wrap(. ~ am,
labeller = label_glue('({.l}) am = {am}')) +
theme_bw(base_size = 12)
Created by the reprex package (v0.2.1)
I think for the answer above lab="Text" is useless, the code below is also ok.
ann_text <- data.frame(mpg = 15,wt = 5,
cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text" )
However if you want to label differently in different sub-graphs, it will be ok in this way:
ann_text <- data.frame(mpg = c(14,15),wt = c(4,5),lab=c("text1","text2"),
cyl = factor(c(6,8),levels = c("4","6","8")))
p + geom_text(data = ann_text,aes(label =lab) )
Expanding slightly on joran's excellent answer, to clarify how the label dataframe works.
You can think of "mpg" and "wt" as the x and y coordinates, respectively (I find it easier to keep track of the original variable names than renaming them, as in Kamil's also-excellent answer). You need one row per label, and the "cyl" column shows which facet each row is associated with.
ann_text<-data.frame(mpg=c(25,15),wt=c(3,5),cyl=c(6,8),label=c("Label 1","Label 2"))
ann_text
> mpg wt cyl label
> 25 3 6 Label 1
> 15 5 8 Label 2
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ factor(cyl))
p + geom_text(data = ann_text,label=ann_text$label)
I did not know about the egg package,
so here is a plain ggplot2 package solution
library(tidyverse)
library(magrittr)
Data1=data.frame(A=runif(20, min = 0, max = 100), B=runif(20, min = 0, max = 250), C=runif(20, min = 0, max = 300))
Data2=data.frame(A=runif(20, min = -10, max = 50), B=runif(20, min = -5, max = 150), C=runif(20, min = 5, max = 200))
bind_cols(
Data1 %>% gather("Vars","Data_1"),
Data2 %>% gather("Vars","Data_2")
) %>% select(-Vars1) -> Data_combined
Data_combined %>%
group_by(Vars) %>%
summarise(r=cor(Data_1,Data_2),
r2=r^2,
p=(pt(abs(r),nrow(.)-2)-pt(-abs(r),nrow(.)-2))) %>%
mutate(rlabel=paste("r:",format(r,digits=3)),
plabel=paste("p:",format(p,digits=3))) ->
label_df
label_df %<>% mutate(x=60,y=190)
Data_combined %>%
ggplot(aes(x=Data_1,y=Data_2,color=Vars)) +
geom_point() +
geom_smooth(method="lm",se=FALSE) +
geom_text(data=label_df,aes(x=x,y=y,label=rlabel),inherit.aes = FALSE) +
geom_text(data=label_df,aes(x=x,y=y-10,label=plabel),inherit.aes = FALSE) +
facet_wrap(~ Vars)

ggplot2 add sum to chart

Using mtcars as an example, I've produced some violin plots. I wanted to add two things to this chart:
for each group, list n
for each group, sum a third variable (e.g. wt)
I can do (1) with the geom_text code below although (n) is actually plotted on the x axis rather than off to the side.
But I can't work out how to do (2).
Any help much appreciated!
library(ggplot2)
library(gridExtra)
library(ggthemes)
result <- mtcars
ggplot(result, aes(x = gear, y = drat, , group=gear)) +
theme_tufte(base_size = 15) + theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(stat = "count", aes(label = ..count.., y = ..count..))
You can add both of these annotations by creating them in your dataframe temporarily prior to graphing. Using the dplyr package, you can create two new columns, one with the count for each group, and one with the sum of wt for each group. This can then be piped directly into your ggplot using %>% (alternatively, you could save the new dataset and insert it into ggplot the way you have it). Then with some minor edits to your geom_text call and adding a second one, we can create the plot you want. The code looks like this:
library(ggplot2)
library(gridExtra)
library(ggthemes)
library(magrittr)
library(dplyr)
result <- mtcars
result %>%
group_by(gear) %>%
mutate(count = n(), sum_wt = sum(wt)) %>%
ggplot(aes(x = gear, y = drat, , group=gear)) +
theme_tufte(base_size = 15) + theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(aes(label = paste0("n = ", count),
x = (gear + 0.25),
y = 4.75)) +
geom_text(aes(label = paste0("sum wt = ", sum_wt),
x = (gear - 0.25),
y = 4.75))
The new graph looks like this:
Alternatively, if you create a summary data frame named result_sum, then you can manually add that into the geom_text calls.
result <- mtcars %>%
mutate(gear = factor(as.character(gear)))
result_sum <- result %>%
group_by(gear) %>%
summarise(count = n(), sum_wt = sum(wt))
ggplot(result, aes(x = gear, y = drat, , group=gear)) +
theme_tufte(base_size = 15) +
theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(data = result_sum, aes(label = paste0("n = ", count),
x = (as.numeric(gear) + 0.25),
y = 4.75)) +
geom_text(data = result_sum, aes(label = paste0("sum wt = ", sum_wt),
x = (as.numeric(gear) - 0.25),
y = 4.75))
This gives you this:
The benefit to this second method is that the text isn't bold like in the first graph. The bold effect occurs in the first graph due to the text being printed over itself for all observations in the dataframe.
Thanks to those who helped.... I used this in the end which plots the calculated values, one set of classes being text based so using vjust to position the vertical offset.
thanks again!
library(ggplot2)
library(gridExtra)
library(ggthemes)
results <- mtcars
results$gear <- as.factor(as.character(results$gear)) #Turn 'gear' to text to simulate classes, then factorise
result_sum <- results %>%
group_by(gear) %>%
summarise(count = n(), sum_wt = sum(wt))
ggplot(results, aes(x = gear, y = drat, group=gear)) +
theme_tufte(base_size = 15) + theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(data = result_sum, aes(label = paste0("n = ", count), x = (gear), vjust= 0, y = 5.25)) +
geom_text(data = result_sum, aes(label = paste0("sum wt = ", round(sum_wt,0)), x = (gear), vjust= -2, y = 5.25))

Print Regression Coefficients on Graph (ggplot)

I perform a regression with reg <- lm(...) and get some coefficents I can access with reg$coefficients.
It's of type Named num and contains all the coefficients with their values.
Named num [1:11] 505.085 -0.251 -0.286 -0.22 -0.801 ...
- attr(*, "names")= chr [1:11] "(Intercept)" "year" "monthDez" "monthFeb" ...
I want to show these on my graph created with ggplot. My current approach was to use the subtitle for this:
labs(subtitle=paste(toString(names(reg$coefficients)), "\n",
paste(reg$coefficients, collapse = " ")))
But it's not aligned correctly (name directly over the value etc.)
Has someone an idea?
My current plot looks like this:
base <- ggplot(deliveries, aes(Date)) +
geom_line(aes(y = SalesVolume, colour = "SalesVolume"))+
ggtitle("Sales Volume By Time") +
xlab("Time") +
ylab("Sales Volume") +
labs(subtitle=paste(toString(names(reg$coefficients)), "\n", paste(reg$coefficients, collapse = " ")))
print(base + scale_x_date(labels = date_format("%b %y"), breaks = date_breaks("2 months")))
In this graph a forecast is displayed, so I want to see the regression coefficients there as well.
Would it work to make two separate plots and arrange them onto a grid?
library(ggplot2)
library(broom)
library(dplyr)
library(tidyr)
data_plot <-
ggplot(data = mtcars,
mapping = aes(x = qsec,
y = mpg,
colour = factor(gear))) +
geom_point()
fit <- lm(mpg ~ qsec + wt + factor(gear),
data = mtcars)
# Make a data frame with the contents of the model.
reg_data <-
tidy(fit) %>%
mutate(y = nrow(.):1 - 1) %>%
gather(estimate, value,
estimate:p.value) %>%
mutate(estimate = factor(estimate,
c("term", "estimate", "std.error",
"statistic", "p.value")))
# Make a plot displaying the table.
reg_plot <-
ggplot(data = reg_data,
mapping = aes(x = estimate,
y = y)) +
geom_text(mapping = aes(label = round(value, 2))) +
scale_y_continuous(breaks = unique(reg_data[["y"]]),
labels = unique(reg_data[["term"]])) +
scale_x_discrete(position = "top") +
xlab("") +
ylab("") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_blank())
# Arrange the two plots
gridExtra::grid.arrange(data_plot + theme(plot.margin = grid::unit(c(1,1,0,.5), "lines")),
reg_plot + theme(plot.margin = grid::unit(c(0,0,1,0), "lines")),
clip = FALSE,
nrow = 2,
ncol = 1,
heights = grid::unit(c(.70, .5),
c("null", "null")))
In my limited experience with ggplot2, annotate() could be used to add some annotations to a plot created with ggplot(), but I am not sure if the code below works for what you want
reg <- lm(data = mtcars, mpg ~ wt)
pred <- predict(reg)
newdata <- data.frame(mtcars, pred)
par <- summary(reg)$coefficients[,1] # extract model parameters
par.f <- format(par, digits = 2) # set the decimal digits of parameters
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
geom_line(data = newdata, aes(x = wt, y = pred)) +
annotate("text", x = c(2, 2.5), y = 18, label = names(reg$coefficients)) +
annotate("text", x = c(2, 2.5), y = 16.5, label = par.f) # make them aligned by set x and y in annotate()
enter image description here

Resources