Could you please help me how to generate the 3D plot something as below?
dat <- tibble::tribble(
~subject, ~response, ~duration,
'1', 10, 20,
'2', -7, 30,
'3', 5, 20,
'4', 7, 50,
'5', -5, 40
)
Here's something a little closer to the original using plot3D
First draw the box, axes, title and plane:
library(plot3D)
persp3D(c(min(as.numeric(dat$subject)) - 1, max(as.numeric(dat$subject)) + 1),
c(0, max(dat$duration)),d = 50, phi = 30, theta = 55, xlab = "subject",
ylab = "Duration", zlab = "Response", ticktype = "detailed",
matrix(rep(range(dat$response), 2), 2, 2), lwd = 3,
col.panel = "gray95", colkey = FALSE, bty = "u")
title("Tumor response and duration", cex.main = 2)
rect3D(min(as.numeric(dat$subject)) - 1, 0, min(dat$response),
max(as.numeric(dat$subject)) + 1,
max(dat$duration), NULL,
col = "#e7e7e7", add = TRUE)
rect3D(min(as.numeric(dat$subject)) - 1, 0, min(dat$response),
NULL,
max(dat$duration),
max(dat$response),
col = "#e0e0e0", add = TRUE)
rect3D(min(as.numeric(dat$subject)) - 1, max(dat$duration), min(dat$response),
max(as.numeric(dat$subject)) + 1, NULL,
max(dat$response),
col = "#f0f0f0", add = TRUE)
rect3D(min(as.numeric(dat$subject)) - 1, 0, 0,
max(as.numeric(dat$subject)) + 1,
max(dat$duration), NULL,
col = "#FFFFFF20", border = "gray50", add = TRUE)
Now the bars using rect3D
for(i in seq(nrow(dat))) {
rect3D(as.numeric(dat$subject[i]) - 0.2, 0, 0,
as.numeric(dat$subject[i]) + 0.2, dat$duration[i], NULL,
col = "#7c95ca", add = TRUE)
}
for(i in seq(nrow(dat))) {
rect3D(as.numeric(dat$subject[i]) - 0.2, 0, 0,
as.numeric(dat$subject[i]) + 0.2, NULL,
dat$response[i],
col = "#de7e6f", add = TRUE)
}
Finally, add the box outlines:
lines3D(c(min(as.numeric(dat$subject)) - 1, max(as.numeric(dat$subject)) + 1),
c(0, 0), rep(max(dat$response), 2), lty = 2, add = TRUE, col = "black")
lines3D(rep(max(as.numeric(dat$subject)) + 1, 2),
c(0, max(dat$duration)), rep(max(dat$response), 2),
lty = 2, add = TRUE, col = "black")
lines3D(rep(max(as.numeric(dat$subject)) + 1, 2),
c(0, 0), range(dat$response),
lty = 2, add = TRUE, col = "black")
lines3D(c(rep(min(as.numeric(dat$subject)) - 1, 3),
rep(max(as.numeric(dat$subject)) + 1, 3),
min(as.numeric(dat$subject)) - 1),
c(0, 0, rep(max(dat$duration), 3), 0, 0),
c(min(dat$response), rep(max(dat$response), 3),
rep(min(dat$response),3)),add = TRUE, col = "black", lwd = 5)
However, as others have pointed out in the comments, although such a plot is superficially impressive, it is actually less useful than displaying the data in a more familiar, elegant 2-D plot. Such a plot is also far easier to create, and contains all the same information in a more readable format
library(ggplot2)
ggplot(dat, aes(response, duration)) +
geom_point(size = 6, aes(color = "(subject id)"), alpha = 0.5) +
geom_text(aes(label = subject), nudge_x = 0.5, nudge_y = 1) +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 0) +
ggtitle("Tumor response versus duration") +
scale_color_manual(NULL, values = "navy") +
theme_minimal(base_size = 20) +
theme(plot.margin = margin(20, 20, 50, 20),
plot.title = element_text(size = 32, color = "gray20",
margin = margin(10, 10, 50, 10)))
I think you'll have to write that yourself. Here are a couple of half-hearted attempts; you'll need to clean them up a lot.
library(scatterplot3d)
dat <- tibble::tribble(
~subject, ~response, ~duration,
'1', 10, 20,
'2', -7, 30,
'3', 5, 20,
'4', 7, 50,
'5', -5, 40
)
rectx <- c(-0.4, 0.4, 0.4, -0.4, -0.4, NA)
recty <- c(0, 0, 1, 1, 0, NA)
rectangles <- data.frame(x = numeric(), y = numeric(), z = numeric() )
for (i in seq_len(nrow(dat))) {
subj <- as.numeric(dat$subject[i])
rectangles <- rbind(rectangles,
data.frame(x = rectx + subj,
y = 0,
z = recty*dat$response[i]),
data.frame(x = rectx + subj,
y = recty*dat$duration[i],
z = 0))
}
with(dat, scatterplot3d(x = rectangles,
type= "l",
xlab = "Subject",
ylab = "Duration",
zlab = "Response"))
i <- seq_len(nrow(rectangles))
drop <- which(is.na(rectangles[i, 1]) )
drop <- c(drop, drop-1)
rectangles <- rectangles[!(i %in% drop),]
library(rgl)
open3d()
#> glX
#> 1
quads3d(rectangles, col = c(rep("red",4), rep("blue", 4)))
aspect3d(1,1,1)
decorate3d(xlab = "Subject",
ylab = "Duration",
zlab = "Response")
Created on 2023-01-07 with reprex v2.0.2
Related
I have my data
varechem <-
structure(
list(
`POX-C` = c(
869.153225806452,
841.409274193548,
720.344758064516,
828.798387096774,
904.46370967742,
773.310483870968,
793.487903225806,
874.197580645161,
900.932661290323,
778.354838709677
),
`B-glucosidase` = c(
1.90612612612613,
1.60509009009009,
1.42864864864865,
1.82355855855856,
1.76761261261261,
1.34855855855856,
1.37504504504504,
1.5863963963964,
1.1290990990991,
1.4686036036036
),
Protein = c(
6284.21052631579,
6250.52631578947,
6103.15789473684,
6280,
6275.78947368421,
4368.42105263158,
1240,
6191.57894736842,
5745.26315789474,
6970.52631578947
)
),
row.names = c(
"M.T1.R1.S1.16S.S50",
"M.T1.R1.S2.16S.S62",
"M.T1.R1.S3.16S.S74",
"M.T1.R2.S1.16S.S86",
"M.T1.R2.S2.16S.S3",
"M.T1.R2.S3.16S.S15",
"M.T1.R3.S1.16S.S27",
"M.T1.R3.S2.16S.S39",
"M.T1.R3.S3.16S.S51",
"M.T1.R4.S1.16S.S63"
),
class = "data.frame"
)
varespec <-
structure(
list(
A = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
B = c(1,
1, 1, 1, 1, 1, 1, 1, 1, 1),
C = c(1, 1, 1, 2, 1, 1, 1, 1, 1,
3),
D = c(2, 1, 1, 1, 1, 1, 1, 1, 1, 1),
E = c(1, 1, 1, 1, 1,
3, 1, 1, 1, 1),
F = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
G = c(1,
1, 11, 20, 15, 13, 23, 9, 1, 16),
H = c(2, 1, 1, 4, 1, 1, 1,
1, 1, 1),
I = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
J = c(9, 3, 20,
21, 16, 19, 22, 13, 12, 26)
),
row.names = c(
"M.T1.R1.S1.16S.S50",
"M.T1.R1.S2.16S.S62",
"M.T1.R1.S3.16S.S74",
"M.T1.R2.S1.16S.S86",
"M.T1.R2.S2.16S.S3",
"M.T1.R2.S3.16S.S15",
"M.T1.R3.S1.16S.S27",
"M.T1.R3.S2.16S.S39",
"M.T1.R3.S3.16S.S51",
"M.T1.R4.S1.16S.S63"
),
class = "data.frame"
)
I have my codes:
library(ggplot2); library(vegan)
sol <- cca(varespec, varechem)
scrs<-scores(sol,display=c("sp","wa","lc","bp","cn"))
df_sites <- data.frame(scrs$sites)
df_sites$Sites <- gsub("\\..*", "", rownames(varechem))
df_sites$Sites <- factor(df_sites$Sites)
# rownames(df_sites) <- gsub("[*].*$", "",rownames(df_sites))
colnames(df_sites)<-c("x","y","Sites")
#Draw sites
p<-ggplot()
p<-p+geom_point(data=df_sites,aes(x,y,colour=Sites), shape = "diamond", size = 2)
p <- p + scale_colour_manual(values = c("blue"), guide = FALSE)
p
#Draw biplots
multiplier <- vegan:::ordiArrowMul(scrs$biplot)
df_arrows<- scrs$biplot*multiplier
colnames(df_arrows)<-c("x","y")
df_arrows=as.data.frame(df_arrows)
#adding arrows for chemicals (environment variables)
pa<-p+geom_segment(data=df_arrows, aes(x = 0, y = 0, xend = x, yend = y),
arrow = arrow(length = unit(0.3, "cm")), arrow.fill = "black")
pa
###adjust the position of the labels or shapes
df_arrows <- as.data.frame(df_arrows*1.1)
df_arrows$Chemicals <- factor(rownames(df_arrows))
cp <- pa+geom_point(data= df_arrows, aes(x, y, group= Chemicals, shape = Chemicals), size = 4) + scale_shape_manual(values=1:nlevels(df_arrows$Chemicals)) + coord_equal()
#### # Draw species
df_species<- as.data.frame(scrs$species)
colnames(df_species)<-c("x","y")
significant_taxa <- c("A", "D")
df_species$significant <- ifelse(rownames(df_species) %in% significant_taxa, "Sig", "Not-sig")
df_species$significant <- as.character(df_species$significant)
get.colour <- c("red", "orange")
#relevel factor so "Sig" will appear first in the legend
df_species$significant <- factor(df_species$significant, levels = c("Sig", "Not-sig"))
df_species$coloured <- "black"
df_species$coloured [match(significant_taxa, rownames(df_species))] <- get.colour
df_species$coloured <- as.factor(df_species$coloured)
library(dplyr)
df_species <- df_species %>%
mutate(labels = rownames(df_species))
scp <- cp+geom_point(data=df_species,aes(x=x,y=y, group = significant, size = significant))+
scale_size_manual(values =c(2.5, 0.2))
scp
library(ggrepel)
scp + geom_text_repel(data = subset(df_species, significant == "Sig"),
aes(x = x, y = y, label = labels), angle = 60, size = 3)
I am having problem colouring only A and D text and the corresponding two data points in different colours (say green and red). How can I do this ?
I think your error is about the use of group = significant in the geom_point, it prevents for the definition of color. If you use this code, you will get the right plot:
ggplot() +
geom_point(data=df_sites,aes(x,y), color = "blue", shape = "diamond", size = 2) +
geom_segment(data=df_arrows, aes(x = 0, y = 0, xend = x, yend = y),
arrow = arrow(length = unit(0.3, "cm")), arrow.fill = "black") +
geom_point(data= df_arrows, aes(x, y, group= Chemicals, shape = Chemicals), size = 4) +
scale_shape_manual(values=1:nlevels(df_arrows$Chemicals)) +
coord_equal() +
geom_point(data = df_species, aes(x = x, y = y, color = coloured, size = significant)) +
scale_size_manual(values = c(2.5, 1)) +
geom_text_repel(data = subset(df_species, significant == "Sig"),
aes(x = x, y = y, label = labels, color = coloured), angle = 60, size = 3) +
scale_color_manual(values = c("black","orange","red"), guide = FALSE)
I have my data
varechem <-
structure(
list(
`POX-C` = c(
869.153225806452,
841.409274193548,
720.344758064516,
828.798387096774,
904.46370967742,
773.310483870968,
793.487903225806,
874.197580645161,
900.932661290323,
778.354838709677
),
`B-glucosidase` = c(
1.90612612612613,
1.60509009009009,
1.42864864864865,
1.82355855855856,
1.76761261261261,
1.34855855855856,
1.37504504504504,
1.5863963963964,
1.1290990990991,
1.4686036036036
),
Protein = c(
6284.21052631579,
6250.52631578947,
6103.15789473684,
6280,
6275.78947368421,
4368.42105263158,
1240,
6191.57894736842,
5745.26315789474,
6970.52631578947
)
),
row.names = c(
"M.T1.R1.S1.16S.S50",
"M.T1.R1.S2.16S.S62",
"M.T1.R1.S3.16S.S74",
"M.T1.R2.S1.16S.S86",
"M.T1.R2.S2.16S.S3",
"M.T1.R2.S3.16S.S15",
"M.T1.R3.S1.16S.S27",
"M.T1.R3.S2.16S.S39",
"M.T1.R3.S3.16S.S51",
"M.T1.R4.S1.16S.S63"
),
class = "data.frame"
)
varespec <-
structure(
list(
A = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
B = c(1,
1, 1, 1, 1, 1, 1, 1, 1, 1),
C = c(1, 1, 1, 2, 1, 1, 1, 1, 1,
3),
D = c(2, 1, 1, 1, 1, 1, 1, 1, 1, 1),
E = c(1, 1, 1, 1, 1,
3, 1, 1, 1, 1),
F = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
G = c(1,
1, 11, 20, 15, 13, 23, 9, 1, 16),
H = c(2, 1, 1, 4, 1, 1, 1,
1, 1, 1),
I = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
J = c(9, 3, 20,
21, 16, 19, 22, 13, 12, 26)
),
row.names = c(
"M.T1.R1.S1.16S.S50",
"M.T1.R1.S2.16S.S62",
"M.T1.R1.S3.16S.S74",
"M.T1.R2.S1.16S.S86",
"M.T1.R2.S2.16S.S3",
"M.T1.R2.S3.16S.S15",
"M.T1.R3.S1.16S.S27",
"M.T1.R3.S2.16S.S39",
"M.T1.R3.S3.16S.S51",
"M.T1.R4.S1.16S.S63"
),
class = "data.frame"
)
I have my codes:
library(vegan); library(ggplot2)
sol <- cca(varespec, varechem)
scrs <- scores(sol, display = c("sp", "wa", "lc", "bp", "cn"))
df_sites <- data.frame(scrs$sites)
df_sites$Sites <- gsub("\\..*", "", rownames(varechem))
df_sites$Sites <- factor(df_sites$Sites)
# rownames(df_sites) <- gsub("[*].*$", "",rownames(df_sites))
colnames(df_sites) <- c("x", "y", "Sites")
#Draw sites
p <- ggplot()
p <-
p + geom_point(
data = df_sites,
aes(x, y, colour = Sites),
shape = "diamond",
size = 2
)
p <- p + scale_colour_manual(values = c("blue"), guide = FALSE)
p
#Draw biplots
multiplier <- vegan:::ordiArrowMul(scrs$biplot)
df_arrows <- scrs$biplot * multiplier
colnames(df_arrows) <- c("x", "y")
df_arrows = as.data.frame(df_arrows)
#adding arrows for chemicals (environment variables)
pa <-
p + geom_segment(
data = df_arrows,
aes(
x = 0,
y = 0,
xend = x,
yend = y
),
arrow = arrow(length = unit(0.3, "cm")),
arrow.fill = "black"
)
pa
###adjust the position of the labels or shapes
df_arrows <- as.data.frame(df_arrows * 1.1)
df_arrows$Chemicals <- factor(rownames(df_arrows))
cp <-
pa + geom_point(data = df_arrows,
aes(x, y, group = Chemicals, shape = Chemicals),
size = 4) + scale_shape_manual(values = 1:nlevels(df_arrows$Chemicals))
#### # Draw species
df_species <- as.data.frame(scrs$species)
colnames(df_species) <- c("x", "y")
significant_taxa <- c("A", "D")
df_species$significant <-
ifelse(rownames(df_species) %in% significant_taxa, "Sig", "Not-sig")
df_species$significant <- as.character(df_species$significant)
get.colour <- c("red", "orange")
# scp <- cp + geom_point(data = df_species, aes(x, y), size = 0.5)
#relevel factor so "Sig" will appear first in the legend
df_species$significant <-
factor(df_species$significant, levels = c("Sig", "Not-sig"))
df_species$coloured <- "black"
df_species$coloured [match(significant_taxa, rownames(df_species))] <-
get.colour
df_species$coloured <- as.factor(df_species$coloured)
This is where I need help. I need to put two colours for siginficant values
(Sig only) from df_species$coloured and get their labels from the dataframe
rownames(df_species) which is A and D in their respective font colours. So I
would like to put two colours and text associated with that A and D. How
can I do this?
scp <- cp + geom_point(data = df_species, aes(x, y, group = significant, size = significant)) +
scale_size_manual(values = c(4.5, 0.2))
scp
I think I have a solution. I added an extra column to df_species to create the labels in the plot.
df_species <- df_species %>%
mutate(labels = rownames(df_species))
The plot: (This part is updated based on the comment of the OP.)
scp <- ggplot() +
geom_point(data = df_species,
aes(x = x,
y = y,
colour = coloured,
size = significant)) +
geom_text(data = subset(df_species, significant == "Sig"),
aes(x = x,
y = y,
label = labels,
colour = coloured),
hjust = 1,
vjust = -1,
show.legend = FALSE) +
scale_colour_manual(values = c("black" = "black", "red" = "red", "orange" = "orange")) +
scale_size_manual(values = c(4.5, 0.2)) +
geom_point(data = df_sites,
aes(x = x,
y = y,
fill = Sites),
size = 2,
pch = 23) + # with this shape you can use fill
scale_fill_manual(values = c("M" = "blue")) +
geom_point(data = df_arrows,
aes(x = x,
y = y,
group = Chemicals,
shape = Chemicals),
size = 4) +
scale_shape_manual(values = 1:nlevels(df_arrows$Chemicals)) +
geom_segment(data = df_arrows,
aes(x = 0,
y = 0,
xend = x,
yend = y),
arrow = arrow(length = unit(0.3, "cm")),
arrow.fill = "black")
scp
It took a bit of playing around, but I hope this is what you where looking for. :-) I added everything together. For me this was a bit easier to get the overview. The position / order of the scale_* functions is important.
How could I create a simple plot of a coordinate system within two vectors in R? It should look like the following plot.
Thank you!
# Empty plot
plot(1, 1, type = "n", xlim = c(-3, 3), ylim = c(-3, 3), asp = 1,
ann = FALSE, axes = FALSE)
# Axes
arrows(x0 = -3, y0 = 0, x1 = 3, y1 = 0, length = 0.1, code = 3)
arrows(x0 = 0, y0 = -3, x1 = 0, y1 = 3, length = 0.1, code = 3)
# Vectors
# v1
arrows(0, 0, 2.5, 1, length = 0.1, col = "lightblue", lwd = 2)
# v2
arrows(0, 0, 1, 2, length = 0.1, col = "blue", lwd = 2)
# v3
arrows(1, 2, 2.5, 1, length = 0.1, col = "red", lwd = 2)
# Text
text(x = mean(c(0, 2.5)), y = mean(c(0, 1)), labels = "v1", pos = 1)
text(0.5, 1, "v2", pos = 3)
text(1.75, 1.5, "v3", pos = 4)
I am creating a plot where I plot the variable on the X-axis against that on the Y-axis, and I am adding histograms of the variables as well. I have added a trend-line to the plot using abline().
The problem is that it does not appear to respect the xlim = c(0, 20) in the plot region as it extends beyond the limits of the x-axis. I tried playing around with the xpd option, but to no avail. Next I tried fiddling with the different par()options, but found nothing that could help with this issue.
What I want is for the trend-line to be the exact length of the x-axis. Any help is much appreciated. In this particular case the trend-line is almost flat, but the slope will change when I do the same for other variables.
MWE -- NOTE: I am only providing 15 data points to illustrate the issue so the graph will differ from the image provided.
df.data <- data.frame(id = 1:15,
ll = c(-9.53026, -6.50640,-6.50640, -7.68535, -11.80899, -8.42790,
-6.50640, -6.50640, -7.92405, -6.50640, -8.95522, -9.99228,
-10.02286, -8.95969, -6.07313),
aspm = c(4.582104, 0.490244, 0.737765, 0.256699, 1.575931, 1.062693,
1.006984, 0.590355, 1.014370, 0.924855, 0.735989, 0.831025,
1.197886, 1.143220, 0.928068))
str.col.light.blue <- c(rgb(r = 110/255, g = 155/255, b = 225/255))
str.col.dark.blue <- c(rgb(r = 50/255, g = 100/255, b = 185/255))
layout(matrix(c(2, 4, 1, 3), 2, 2, byrow = TRUE), widths = c(5, 2), heights = c(2, 5))
layout.show(4)
par(omi = c(0.1, 0.1, 0.1, 0.1))
par(mar = c(2, 2, 0, 0))
par(mai = c(1, 1, 0, 0))
plot(df.data[, "ll"] ~ df.data[, "aspm"], col = str.col.light.blue,
xlim = c(0, 20), ylim = c(-15, -5), axes = FALSE,
xlab = "X1", ylab = "X2",
cex.lab = 1.25)
abline(a = -8.156670, b = -0.000879, lty = 5, col = "black", lwd = 2, xpd = FALSE)
axis(1, at = seq(0, 20, by = 5), labels = seq(0, 20, by = 5), cex.axis = 1)
axis(2, at = seq(-15, -5, by = 3), labels = seq(-15, -5, by = 3), cex.axis = 1, las = 1)
rect(0, -15, 20, log(1/3)*8, density = 10, angle = 45, lwd = 0.5, col = "gray")
par(mar = c(0, 2, 0, 0))
par(mai = c(0, 1, 0.25, 0))
x.hist <- hist(df.data[, "aspm"], plot = FALSE, breaks = 20)
barplot(x.hist$density, axes = FALSE, horiz = FALSE, space = 0, col = str.col.dark.blue)
par(mar = c(2, 0, 0, 0))
par(mai = c(1, 0, 0, 0.25))
y.hist <- hist(df.data[, "ll"], plot = FALSE, breaks = 20)
barplot(y.hist$density, axes = FALSE, horiz = TRUE, space = 0, col = str.col.dark.blue)
In order to avoid working out the start and end points of the segments, you can program a helper function to do it for you.
linear <- function(x, a, b) a + b*x
Then, I've used your code with the following changes. abline was replaced by segments, with all the graphics parameters you had used in your original call.
x0 <- 0
y0 <- linear(x0, a = -8.156670, b = -0.000879)
x1 <- 20
y1 <- linear(x1, a = -8.156670, b = -0.000879)
segments(x0, y0, x1, y1, lty = 5, col = "black", lwd = 2, xpd = FALSE)
This call to segment was placed where ablinewas.
In the final graph, I see a well behaved segment.
(reproducible code given) I am studying Ugarte2016's "Probability and Statistics with R" 2E. The following code is run in R but Latex-like code is not processed. It seems that the code inside "$...$" is not processed. The code supplied below was from the authors of the book. There seems a problem somehow. What could be the problem?
######### Chapter 12 #############
library(PASWR2); library(ggplot2); library(car); library(scatterplot3d)
library(gridExtra); library(multcomp); library(leaps); library(MASS)
################ Figure 12.1 ###############
opar <- par(no.readonly = TRUE) # copy of current settings
par(mar=c(2, 14, 2, 1), las = 1)
DF <- data.frame(x = c(1, 4, 9), y = c(1, 4, 9))
plot(y~x, data = DF, xaxt = "n", yaxt = "n", xlim = c(0, 12), ylim = c(-2, 12), xlab = "", ylab = "", type = "n")
abline(lm(y~x, data = DF), lwd = 2)
axis(side =1, at =c(1, 4, 10), labels = c("$x_1$", "$x_2$", "$x_3$"))
axis(side =2, at =c(1, 4, 10), labels = c("$E(Y|x_1) = \\beta_0 + \\beta_1x_1$", "$E(Y|x_1) = \\beta_0 + \\beta_1x_1$", "$E(Y|x_1) = \\beta_0 + \\beta_1x_1$") )
segments(1, -2, 1, 2.5, lty = "dashed")
segments(0, 1, 1 + 0.75, 1, lty = "dashed")
segments(4, -2, 4, 5.5, lty = "dashed")
segments(0, 4, 4 + 0.75, 4, lty = "dashed")
segments(10, -2, 10, 11.5, lty = "dashed")
segments(0, 10, 10 + 0.75, 10, lty = "dashed")
ys <- seq(-1.5, 1.5, length = 200)
xs <- dnorm(ys, 0, 0.5)
lines(xs + 1, ys + 1, type = "l",lwd = 2)
lines(xs + 4, ys + 4, type = "l",lwd = 2)
lines(xs + 10, ys + 10, type = "l",lwd = 2)
text(7.8, 5.5, "$E(Y|x) = \\beta_0 + \\beta_1x$")
arrows(8, 5.7, 7, 7, length = 0.1, lwd = 2)
par(opar)
The code result:
The image in the book:
Use package latex2exp:
######### Chapter 12 #############
library(PASWR2); library(ggplot2); library(car); library(scatterplot3d)
library(gridExtra); library(multcomp); library(leaps); library(MASS)
library(latex2exp)
################ Figure 12.1 ###############
opar <- par(no.readonly = TRUE) # copy of current settings
par(mar=c(2, 14, 2, 1), las = 1)
DF <- data.frame(x = c(1, 4, 9), y = c(1, 4, 9))
plot(y~x, data = DF, xaxt = "n", yaxt = "n", xlim = c(0, 12), ylim = c(-2, 12), xlab = "", ylab = "", type = "n")
abline(lm(y~x, data = DF), lwd = 2)
axis(side =1, at =c(1, 4, 10), labels = TeX(c("$x_1$", "$x_2$", "$x_3$")))
axis(side =2, at =c(1, 4, 10), labels = TeX(c("$E(Y|x_1) = \\beta_0 + \\beta_1x_1$", "$E(Y|x_1) = \\beta_0 + \\beta_1x_1$", "$E(Y|x_1) = \\beta_0 + \\beta_1x_1$") ))
segments(1, -2, 1, 2.5, lty = "dashed")
segments(0, 1, 1 + 0.75, 1, lty = "dashed")
segments(4, -2, 4, 5.5, lty = "dashed")
segments(0, 4, 4 + 0.75, 4, lty = "dashed")
segments(10, -2, 10, 11.5, lty = "dashed")
segments(0, 10, 10 + 0.75, 10, lty = "dashed")
ys <- seq(-1.5, 1.5, length = 200)
xs <- dnorm(ys, 0, 0.5)
lines(xs + 1, ys + 1, type = "l",lwd = 2)
lines(xs + 4, ys + 4, type = "l",lwd = 2)
lines(xs + 10, ys + 10, type = "l",lwd = 2)
text(7.8, 5.5, TeX("$E(Y|x) = \\beta_0 + \\beta_1x$"))
arrows(8, 5.7, 7, 7, length = 0.1, lwd = 2)
par(opar)
All graphs in the book were created running the knitr option dev = "tikz"...specifically for the graph in question:
<<c12slrModFIG, echo = FALSE, dev = "tikz", crop = TRUE, fig.align = 'center', results = 'hide', fig.height = 5, fig.width = 7, out.width='0.95\\linewidth', warning = FALSE>>=
The solution of sandipan uses latex2exp::TeX. There is a solution that keeps the original code and does not use latex2exp::TeX at all.
When I contacted the authors of the book, they generously sent a code and specified that they used tikzDevice and knitr to produce the graphs. Being novice to both knitr/tkizDevice, I found a way to obtain the image just as in the book (italic LateX'ed chars on the plot); I am sure there must be a better approach:
The tikzDeviceAndKnitr.Rnw file is put in R's working directory (one may find it via getwd()).
tikzDeviceAndKnitr.Rnw:
<<PASWR2fCh12S1, echo=FALSE, dev="tikz", crop=TRUE, fig.align='center', results='hide', fig.height=5, fig.width=7, out.width='0.95\\linewidth', warning=FALSE>>=
library(tikzDevice)
tikz('tikzDeviceAndKnitr.tex', standAlone=TRUE, width=5, height=5)
opar <- par(no.readonly = TRUE)
par(mar=c(2, 14, 2, 1), las = 1)
DF <- data.frame(x = c(1, 4, 9), y = c(1, 4, 9))
plot(y~x, data = DF, xaxt = "n", yaxt = "n",
xlim = c(0, 12), ylim = c(-2, 12),
xlab = "", ylab = "", type = "n")
abline(lm(y~x, data = DF), lwd = 2)
axis(side =1, at =c(1, 4, 10),
labels = c("$x_1$", "$x_2$", "$x_3$"))
axis(side =2, at =c(1, 4, 10),
labels = c("$E(Y|x_1) = \\beta_0 + \\beta_1x_1$",
"$E(Y|x_1) = \\beta_0 + \\beta_1x_1$",
"$E(Y|x_1) = \\beta_0 + \\beta_1x_1$") )
segments(1, -2, 1, 2.5, lty = "dashed")
segments(0, 1, 1 + 0.75, 1, lty = "dashed")
segments(4, -2, 4, 5.5, lty = "dashed")
segments(0, 4, 4 + 0.75, 4, lty = "dashed")
segments(10, -2, 10, 11.5, lty = "dashed")
segments(0, 10, 10 + 0.75, 10, lty = "dashed")
ys <- seq(-1.5, 1.5, length = 200)
xs <- dnorm(ys, 0, 0.5)
lines(xs + 1, ys + 1, type = "l",lwd = 2)
lines(xs + 4, ys + 4, type = "l",lwd = 2)
lines(xs + 10, ys + 10, type = "l",lwd = 2)
text(7.8, 5.5, "$E(Y|x) = \\beta_0 + \\beta_1x$")
arrows(8, 5.7, 7, 7, length = 0.1, lwd = 2)
par(opar)
dev.off()
tools::texi2dvi('tikzDeviceAndKnitr.tex',pdf=T)
system(paste(getOption('pdfviewer'), 'tikzDeviceAndKnitr.pdf'))
#
In MikTeX of Windows, install packages related with tikz and pgf.
Load the libraries in R and knit the related .Rnw file:
library(PASWR2); library(ggplot2); library(car); library(scatterplot3d)
library(gridExtra); library(multcomp); library(leaps); library(MASS)
library(latex2exp); library(knitr);library(tikzDevice);library(tools)
library(evaluate); library(markdown)
knit("tikzDeviceAndKnitr.Rnw") # The solution ended.
The book's author's reply to me is:
Yes....tikzDevice is used with knitr. The complete code looks like:
\begin{figure}[!ht]
<<c12slrModFIG, echo = FALSE, dev = "tikz", crop = TRUE, fig.align = 'center', results = 'hide', fig.height = 5, fig.width = 7, out.width='0.95\\linewidth', warning = FALSE>>=
opar <- par(no.readonly = TRUE) # copy of current settings
par(mar=c(2, 14, 2, 1), las = 1)
DF <- data.frame(x = c(1, 4, 9), y = c(1, 4, 9))
plot(y~x, data = DF, xaxt = "n", yaxt = "n",
xlim = c(0, 12), ylim = c(-2, 12),
xlab = "", ylab = "", type = "n")
abline(lm(y~x, data = DF), lwd = 2)
axis(side =1, at =c(1, 4, 10),
labels = c("$x_1$", "$x_2$", "$x_3$"))
axis(side =2, at =c(1, 4, 10),
labels = c("$E(Y|x_1) = \\beta_0 + \\beta_1x_1$",
"$E(Y|x_1) = \\beta_0 + \\beta_1x_1$",
"$E(Y|x_1) = \\beta_0 + \\beta_1x_1$") )
segments(1, -2, 1, 2.5, lty = "dashed")
segments(0, 1, 1 + 0.75, 1, lty = "dashed")
segments(4, -2, 4, 5.5, lty = "dashed")
segments(0, 4, 4 + 0.75, 4, lty = "dashed")
segments(10, -2, 10, 11.5, lty = "dashed")
segments(0, 10, 10 + 0.75, 10, lty = "dashed")
ys <- seq(-1.5, 1.5, length = 200)
xs <- dnorm(ys, 0, 0.5)
lines(xs + 1, ys + 1, type = "l",lwd = 2)
lines(xs + 4, ys + 4, type = "l",lwd = 2)
lines(xs + 10, ys + 10, type = "l",lwd = 2)
text(7.8, 5.5, "$E(Y|x) = \\beta_0 + \\beta_1x$")
arrows(8, 5.7, 7, 7, length = 0.1, lwd = 2)
par(opar)
#
\caption{Graphical representation of simple linear regression model
depicting the distribution of $Y$ given x \label{SLRgraph}}
\end{figure}