I have a twoord plot produced with the plotrix package and would like to add a horizontal line representing a particular value to it. The plot is all set up but I need help adding the line.
Here is some sample code:
fake <- matrix(c(1, 2, 3, 4, 5, 22, 30, 47, 98, 62, 20, 40, 10, 15, 15), nrow = 5)
fake <- as.data.frame(m)
horizontallineat <- 50
twrd.p <- twoord.plot(fake$V1,fake$V3,fake$V1,fake$V2, xlab="Bin",
lylim=c(0,100),rylim=c(0,100),type=c("bar","l"),
ylab="Exposure Percentage",rylab="Bin Average PP",
lytickpos=seq(0,100, by = 10),
rytickpos=seq(0,100, by = 10),
ylab.at=50,rylab.at=50,
main="Variable Name",
lcol=3,rcol=4)
This is the plot
Thank you in advance for any insight you are able to offer.
I am not sure whether this is what you want, but you can simply add line with the R-base lines function. Use code like this
library(plotrix) # added library
## your code
fake <- matrix(c(1, 2, 3, 4, 5, 22, 30, 47, 98, 62, 20, 40, 10, 15, 15), nrow = 5)
fake <- as.data.frame(fake) # changed "m" to "fake"
twrd.p <- twoord.plot(fake$V1,fake$V3,fake$V1,fake$V2, xlab="Bin",
lylim=c(0,100),rylim=c(0,100),type=c("bar","l"),
ylab="Exposure Percentage",rylab="Bin Average PP",
lytickpos=seq(0,100, by = 10),
rytickpos=seq(0,100, by = 10),
ylab.at=50,rylab.at=50,
main="Variable Name",
lcol=3,rcol=4)
## simple lines() function with x an y coordinates
## we'll add 2 lines for fun
## 1. dashed, thicker, and red
## 2. dots, thicker and black
lines(x = c(1, 2, 3, 4), y= c(40, 60, 40, 70), lty = 2, lwd = 2, col = "red")
lines(x = c(1.25 , 4.75), y = c(95, 25), lty = 3, lwd=2, col = "black")
This yields the following plot
Adding a short or long horizontal line should be simple now, I hope.
Please let me know whether this is what you had in mind.
Related
I am conducting a kruskal-wallis test to determine statistically significance between three groups of a measurement. I use ggbetweenstats to determine between which group there is a statistically significant association.
Here is the code for sample data and the plot:
sampledata <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20), group = c(1, 2, 3, 1, 2, 3,
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2), measurement = c(0,
1, 200, 30, 1000, 6000, 1, 0, 0, 10000, 20000, 700, 65, 1, 8,
11000, 13000, 7000, 500, 3000)), class = "data.frame", row.names = c(NA,
20L))
library(ggstatsplot)
library(ggplot2)
ggbetweenstats(
data = sampledata,
x = group,
y = measurement,
type = "nonparametric",
plot.type = "box",
pairwise.comparisons = TRUE,
pairwise.display = "all",
centrality.plotting = FALSE,
bf.message = FALSE
)
You can see the results from the kruskal wallis test on the top of the plot as well as the groupes analysis in the plot. Now I want to change y axis to logarithmic scale:
ggbetweenstats(
data = sampledata,
x = group,
y = measurement,
type = "nonparametric",
plot.type = "box",
pairwise.comparisons = TRUE,
pairwise.display = "all",
centrality.plotting = FALSE,
bf.message = FALSE
) +
ggplot2::scale_y_continuous(trans=scales::pseudo_log_trans(sigma = 1, base = exp(1)), limits = c(0,25000), breaks = c(0,1,10,100,1000,10000)
)
However, this removes the grouped analysis. I have tried different scaling solutions and browsed SO for a solution but couldn't find anything. Thank you for your help!
It seems that the y_position parameter in the geom_signif component is not affected by the y axis transformation. You will need to pass the log values of the desired bracket heights manually. In theory, you can pass these via the ggsignif.args parameter, but it seems that in the latest version of ggstatsplot this isn't possible because the y_position is hard-coded.
One way tound this is to store the plot then change the y positions after the fact. Here's a full reprex with the latest versions of ggplot2, ggstatsplot and their dependencies (at the time of writing)
sampledata <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20), group = c(1, 2, 3, 1, 2, 3,
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2), measurement = c(0,
1, 200, 30, 1000, 6000, 1, 0, 0, 10000, 20000, 700, 65, 1, 8,
11000, 13000, 7000, 500, 3000)), class = "data.frame", row.names = c(NA,
20L))
library(ggstatsplot)
library(ggplot2)
library(scales)
p <- ggbetweenstats(
data = sampledata,
x = group,
y = measurement,
type = "nonparametric",
plot.type = "box",
pairwise.comparisons = TRUE,
pairwise.display = "all",
centrality.plotting = FALSE,
bf.message = FALSE
) + scale_y_continuous(trans = pseudo_log_trans(sigma = 1, base = exp(1)),
limits = c(0, exp(13)),
breaks = c(0, 10^(0:5)),
labels = comma)
#> Scale for y is already present.
#> Adding another scale for y, which will replace the existing scale.
i <- which(sapply(p$layers, function(x) inherits(x$geom, "GeomSignif")))
p$layers[[i]]$stat_params$y_position <- c(10, 10.8, 11.6)
p
Created on 2023-01-15 with reprex v2.0.2
these are the vectors that need to all be plotted on the same graph
I would like to plot all of these vectors on one set. I've seen methods using matrices but I can't fathom how I would organize this as a matrix and I also would rather work with the vectors. Is there a method I can use to have these all on a single graph?
x_axis <- c(0, 1, 2, 3, 4, 7)
mouse_r_veh <- c(6, 7, 5, 2, 3, 7)
mouse_r_cap <- c(27, 22, 21, 25, 21, 25)
mouse_rr_veh <- c(7, 3, 4, 6, 4, 17)
mouse_rr_cap <- c(24, 27, 29, 9, 10, 21)
mouse_l_veh <- c(10, 12, 11, 16, 13, 2)
mouse_l_cap <- c(26, 23, 23, 23, 24, 22)
mouse_ll_veh <- c(0, 2, 1, 3, 0, 0)
If you don't want to use matplot, nor yet ggplot, you could just do a single plot call and several lines:
plot(x_axis, ylim = c(0, 30))
lines(mouse_r_cap, col="red")
lines(mouse_r_veh, col = "green")
# ... et cetera
If you don't mind using matplot with a matrix, you could do:
mx <- cbind(x_axis, mouse_r_veh, mouse_r_cap,
mouse_rr_veh, mouse_rr_cap, mouse_l_veh,
mouse_l_cap, mouse_ll_veh)
matplot(mx, type ="l")
You could put the data in a data.frame and use pivot_longer to create a new variable with the name of each serie:
library(tidyr)
library(ggplot2)
df <- data.frame(x_axis,
mouse_r_veh,
mouse_r_cap,
mouse_rr_veh,
mouse_rr_cap,
mouse_l_veh,
mouse_l_cap,
mouse_ll_veh)
data <- df %>% pivot_longer(cols = contains('mouse'))
ggplot(data) + geom_line(aes(x = x_axis, y = value, color = name))
My data looks like this:
mydata <- data.frame(ID = c(1, 2, 3, 5, 6, 7, 9, 11, 12, 13), #patient ID
t1 = c(37, 66, 28, 60, 44, 24, 47, 44, 33, 47), #evaluation before
t4 = c(33, 45, 27, 39, 24, 29, 24, 37, 27, 42), #evaluation after
sexe = c(1, 2, 2, 1, 1, 1, 2, 2, 2, 1)) #subset
I would like to do a simple before-after graph.
So far, I managed to get this:
With this:
library(ggplot2)
ggplot(mydata) +
geom_segment(aes(x = 1, xend = 2, y = t1, yend = t4), size=0.6) +
scale_x_discrete(name = "Intervention", breaks = c("1", "2"), labels = c("T1", "T4"), limits = c(1, 2)) +
scale_y_continuous(name = "Var") + theme_bw()
I am facing multiple issues, can you help me to...
add black circle at the begining and the end of every line? (geom_point() doesn't work)
make line smoother (look how pixelated they are, especially the second one)?
decrease blank space on left and right side of the graph?
add median for T1 and T4 (in red), link those points, compare them with paired mann whitney test and print p-value on the graph?
I would like not to reformat my database to long format I have a lot of other variable and timepoint (not shown here).
I have read other posts (such as here) but solution provided look so complicated for something that seems simple (yet i can't do it...).
Huge thanks for your help!
I will update the graph along with progression :)
EDIT
I would like not to reformat my database to long format as I have a lot of other variables and timepoints (not shown here)...
Here what i would do! Please feel free to ask questions regarding what's going on here.
library(tidyverse)
mydata <- data.frame(ID = c(1, 2, 3, 5, 6, 7, 9, 11, 12, 13), #patient ID
t1 = c(37, 66, 28, 60, 44, 24, 47, 44, 33, 47), #evaluation before
t4 = c(33, 45, 27, 39, 24, 29, 24, 37, 27, 42), #evaluation after
sexe = c(1, 2, 2, 1, 1, 1, 2, 2, 2, 1))
pval <- wilcox.test(x = mydata$t1,y = mydata$t4, paired = T,exact = F)$p.value %>% round(2)
df <- mydata %>%
pivot_longer(2:3,names_to = "Time") %>% # Pivot into long-format
mutate(sexe = as.factor(sexe),
Time = as.factor(Time)) # Make factors
ggplot(df,aes(Time,value,color = sexe,group = ID)) +
geom_point() +
geom_line() +
stat_summary(inherit.aes = F,aes(Time,value),
geom = "point", fun = "median", col = "red",
size = 3, shape = 24,fill = "red"
) +
annotate("text", x = 1.7, y = 60, label = paste('P-Value is',pval)) +
coord_cartesian(xlim = c(1.4,1.6)) +
theme_bw()
Also be aware that it is common to have some variables which repeat through time, in addition to the long format data. See example here:
mydata <- data.frame(ID = c(1, 2, 3, 5, 6, 7, 9, 11, 12, 13), #patient ID
t1 = c(37, 66, 28, 60, 44, 24, 47, 44, 33, 47), #evaluation before
t4 = c(33, 45, 27, 39, 24, 29, 24, 37, 27, 42), #evaluation after
sexe = c(1, 2, 2, 1, 1, 1, 2, 2, 2, 1),
var1 = c(1:10),
var2 = c(1:10),
var3 = c(1:10))
df <- mydata %>%
pivot_longer(2:3,names_to = "Time") %>% # Pivot into long-format
mutate(sexe = as.factor(sexe),
Time = as.factor(Time))
I can address (1) black circles issue:
First, you should tidy your data, so one column holds information of one variable (now 'Var' values on the plot are stored in two columns: 't1' and 't4'). You can achive this with tidyr package.
library(tidyr)
mydata_long <- pivot_longer(mydata, c(t1, t4), names_to = "t")
Now creating points is easy, and the rest of the code becomes a lot clearer:
We can tell ggplot that we want 't' groups on x-axis, their values on y-axis and in case of lines, we want them separate for every 'ID'.
ggplot(mydata_long) +
geom_line(aes(x = t, y = value, group = ID)) + #ploting lines
geom_point(aes(x = t, y = value)) + #ploting points
labs(x = "Intervention", y = "Var") + #changing labels
theme_bw()
I'm trying to save a boxplot in .tiif format using the code below:
sample_01 <- c(6, 1, 6, 8, 9, 8, 7, 3, 4, 9)
sample_02 <- c(13, 17, 16, 22, 18, 14, 20, 20, 11, 19)
sample_03 <- c(25, 23, 26, 29, 29, 22, 30, 27, 26, 21)
sample_04 <- c(31, 37, 40, 36, 33, 34, 31, 32, 37, 35)
sample_05 <- c(41, 44, 43, 47, 45, 50, 41, 45, 43, 50)
tiff(file = "temp.tiff", width = 3200, height = 3200, units = "px", res = 300)
box <- boxplot(sample_01,sample_02,sample_03,sample_04,sample_05,
names = c("sample_01","sample_02","sample_03","sample_04","sample_05"),
ylab = 'Relative Abundance (%)',
ylim = c(0,55),
col = c('red','green','blue','orange','purple'),
las=2,
cex.axis = 1.5,
cex.lab = 1.5
)
dev.off()
However, variable names are always cut on the graph's x-axis. I tried to use the parameter par(mar = c ()) in several different ways but I was unable to solve the problem. I also changed the height and width values, but without success either. How can I proceed so that the names of the x-axis are saved whole.
You can set the margin of your plot by using par(mar = c(bottom,left,top,right)).
As pointed it out by #AndersonNBarbosa, par(mar(...) need to be specified after tiff(...):
tiff(file = "temp.tiff", width = 3200, height = 3200, units = "px", res = 300)
par(mar = c(8,5,2,2))
box <- boxplot(sample_01,sample_02,sample_03,sample_04,sample_05,
names = c("sample_01","sample_02","sample_03","sample_04","sample_05"),
ylab = 'Relative Abundance (%)',
ylim = c(0,55),
col = c('red','green','blue','orange','purple'),
las=2,
cex.axis = 1.5,
cex.lab = 1.5
)
dev.off()
dc37, you noticed me a mistake you were making. In my script, I was using the command par(mar=c()) before tiff() and this was causing error in the graph with the example below:
par(mar = c(8,5,2,2))
tiff(...)
boxplot(...)
dev.off()
Therefore, when saving the image, the command par(mar=c()) must come after tiff() to be all right. As I show below:
tiff(...)
par(mar = c(8,5,2,2))
boxplot(...)
dev.off()
Similar questions to this have been asked, but I have not been able to apply the suggested solutions successfully.
I have created a plot like so;
> elective_ga <- c(68, 51, 29, 10, 5)
> elective_epidural <- c(29, 42, 19, 3, 1)
> elective_cse <- c(0, 0, 0, 20, 7)
> elective_spinal <- c(3, 7, 52, 67, 87)
> years <- c('1982', '1987', '1992', '1997', '2002')
> values <- c(elective_ga, elective_epidural, elective_cse, elective_spinal)
> elective_technique <- data.frame(years, values)
> p <- ggplot(elective_technique, aes(years, values))
> p +geom_bar(stat='identity', aes(fill=c(rep('GA', 5), rep('Epidural', 5), rep('CSE', 5), rep('Spinal', 5)))) +labs(x='Year', y='Percent', fill='Type')
which produces the following chart;
I was expecting the bars to be stacked in the order (from top to bottom) GA, Epidural, CSE, Spinal. I would have thought the way I constructed the data frame that they should be ordered in this way but obviously I have not. Can anyone explain why the bars are ordered the way they are, and how to get them the way I want?
How about this?
elective_ga <- c(68, 51, 29, 10, 5)
elective_epidural <- c(29, 42, 19, 3, 1)
elective_cse <- c(0, 0, 0, 20, 7)
elective_spinal <- c(3, 7, 52, 67, 87)
years <- c('1982', '1987', '1992', '1997', '2002')
values <- c(elective_ga, elective_epidural, elective_cse, elective_spinal)
Type=c(rep('GA', 5), rep('Epidural', 5), rep('CSE', 5), rep('Spinal', 5))
elective_technique <- data.frame(years, values,Type)
elective_technique$Type=factor(elective_technique$Type,levels=c("GA","Epidural","CSE","Spinal"))
p <- ggplot(elective_technique, aes(years, values,fill=Type))+geom_bar(stat='identity') +
labs(x='Year', y='Percent', fill='Type')
One way is to reorder the levels of the factor.
library(ggplot2)
elective_ga <- c(68, 51, 29, 10, 5)
elective_epidural <- c(29, 42, 19, 3, 1)
elective_cse <- c(0, 0, 0, 20, 7)
elective_spinal <- c(3, 7, 52, 67, 87)
years <- c('1982', '1987', '1992', '1997', '2002')
values <- c(elective_ga, elective_epidural, elective_cse, elective_spinal)
type = c(rep('GA', 5), rep('Epidural', 5), rep('CSE', 5), rep('Spinal', 5))
elective_technique <- data.frame(years, values, type)
# reorder levels in factor
elective_technique$type <- factor(elective_technique$type,
levels = c("GA", "Epidural", "CSE", "Spinal"))
p <- ggplot(elective_technique, aes(years, values))
p +
geom_bar(stat='identity', aes(fill = type)) +
labs(x = 'Year', y = 'Percent', fill = 'Type')
The forcats package may provide a cleaner solution.