Missing values in barplot - ggplot2

With the help I already got here on SO, I was able to built the barplot I wanted.
Now I'd like to do exact the same plot using new data that is very similar to the previously one, although it's not working and I can't figure out why.
The data is as it follows:
> dput(pcwdegs)
structure(list(comp = c("C0vsC12", "C0vsC12", "C0vsC24", "C0vsC24",
"C0vsT12", "C0vsT12", "C0vsT24", "C0vsT24", "C12vsC24", "C12vsC24",
"C12vsT12", "C12vsT12", "C12vsT24", "C12vsT24", "C24vsT12", "C24vsT12",
"C24vsT24", "C24vsT24", "T12vsT24", "T12vsT24"), reg = c("up",
"down", "up", "down", "up", "down", "up", "down", "up", "down",
"up", "down", "up", "down", "up", "down", "up", "down", "up",
"down"), count = c(7L, 15L, 11L, 5L, 51L, 50L, 49L, 38L, 10L,
2L, 54L, 44L, 55L, 32L, 24L, 32L, 12L, 17L, 31L, 22L)), class = "data.frame", row.names = c(NA,
-20L))
The code and warning messages I'm getting (saying ALL observations were removed) and the plot:
ggplot(data = pcwdegs,
mapping = aes(x = comp, fill = reg,
y = ifelse(test = reg == "down",
yes = -count, no = count))) +
geom_bar(stat = "identity") +
scale_y_continuous(labels = abs, limits = max(pcwdegs$count) * c(-1.05,1.05)) +
geom_text(aes(label=count), vjust=0.5, color="black", size=3.0, nudge_y = c(-1.5,1.5))+
labs(y = "DEGs related to plant cell wall", x = "Groups comparisons") +
scale_fill_manual(values=c("#98FB98","#FA8072","#00FF00","#FF0000"), name = "Expression regulation", labels = c("down-regulated", "up-regulated")) +
scale_x_discrete(limits=c("T12xT24", "C24xT24", "C24xT12", "C12xT24", "C12xT12", "C12xC24", "C0xT24", "C0xT12", "C0xC24","C0xC12")) +
coord_flip()
Warning messages:
1: Removed 20 rows containing missing values (position_stack).
2: Removed 20 rows containing missing values (geom_text).
3: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
Looking online for solutions, the suggestions were to check if there were NA values (there weren't) and to set higher limits in limits = max(pcwdegs$count) * c(-1.05,1.05) (as it was already suggested on my first question and done). So I still have no clue why such similar data is behaving different to the code.

The problem arises because the categories in your new dataset don't fit into the limits defined by scale_x_discrete. The categories in your new df have an vs in the middle, while in teh limits it's a x. Simply replace x with vs in the limits and everything is fine.
library(ggplot2)
ggplot(data = pcwdegs,
mapping = aes(x = comp, fill = reg,
y = ifelse(test = reg == "down",
yes = -count, no = count))) +
geom_bar(stat = "identity") +
scale_y_continuous(labels = abs, limits = max(pcwdegs$count) * c(-1.05,1.05)) +
geom_text(aes(label=count), vjust=0.5, color="black", size=3.0, nudge_y = c(-1.5,1.5))+
labs(y = "DEGs related to plant cell wall", x = "Groups comparisons") +
scale_fill_manual(values=c("#98FB98","#FA8072","#00FF00","#FF0000"), name = "Expression regulation", labels = c("down-regulated", "up-regulated")) +
#scale_x_discrete(limits=c("T12xT24", "C24xT24", "C24xT12", "C12xT24", "C12xT12", "C12xC24", "C0xT24", "C0xT12", "C0xC24","C0xC12")) +
scale_x_discrete(limits=c("T12vsT24", "C24vsT24", "C24vsT12", "C12vsT24", "C12vsT12", "C12vsC24", "C0vsT24", "C0vsT12", "C0vsC24","C0vsC12")) +
coord_flip()
Created on 2020-05-23 by the reprex package (v0.3.0)

Related

R: How to add vertical line (geom_vline) on plotly (ts_plot)?

I have weekly time series for 2 variables. Now I need to add 2 vertical lines (geom_vline) at "2019-11-10" and "2020-04-26 date points.
structure(list(week = structure(c(18119, 18126, 18133, 18140,
18147, 18154, 18161, 18168, 18175, 18182, 18189, 18196, 18203,
18210, 18217, 18224, 18231, 18238, 18245, 18252, 18259, 18266,
18273, 18280, 18287, 18294, 18301, 18308, 18315, 18322, 18329,
18336, 18343, 18350, 18357, 18364, 18371, 18378, 18385, 18392,
18399, 18406, 18413, 18420, 18427, 18434, 18441, 18448, 18455,
18462, 18469, 18476, 18483, 18490, 18497, 18504, 18511, 18518,
18525, 18532, 18539, 18546, 18553, 18560, 18567, 18574, 18581,
18588, 18595, 18602, 18609, 18616, 18623, 18630, 18637, 18644,
18651, 18658, 18665, 18672, 18679, 18686, 18693, 18700, 18707,
18714, 18721, 18728, 18735, 18742, 18749, 18756, 18763, 18770,
18777, 18784, 18791, 18798, 18805, 18812, 18819, 18826, 18833,
18840, 18847, 18854, 18861, 18868, 18875, 18882, 18889, 18896,
18903, 18910, 18917, 18924, 18931, 18938, 18945, 18952, 18959,
18966, 18973, 18980, 18987, 18994, 19001, 19008, 19015, 19022,
19029, 19036, 19043, 19050, 19057, 19064, 19071, 19078, 19085,
19092, 19099, 19106, 19113, 19120, 19127, 19134, 19141, 19148,
19155, 19162, 19169, 19176, 19183, 19190, 19197, 19204, 19211,
19218, 19225, 19232, 19239, 19246, 19253, 19260, 19267), class = "Date"),
X = c(6L, 104L, 123L, 82L, 67L, 108L, 89L, 1153L, 311L, 346L,
220L, 219L, 184L, 257L, 585L, 342L, 197L, 184L, 351L, 278L,
120L, 204L, 206L, 146L, 216L, 186L, 171L, 200L, 198L, 170L,
192L, 139L, 136L, 414L, 256L, 306L, 281L, 221L, 271L, 311L,
315L, 277L, 342L, 394L, 493L, 855L, 1617L, 954L, 1143L, 1031L,
692L, 380L, 378L, 493L, 381L, 706L, 546L, 653L, 447L, 1004L,
499L, 442L, 926L, 564L, 568L, 755L, 581L, 572L, 780L, 601L,
739L, 563L, 300L, 454L, 727L, 733L, 673L, 648L, 614L, 754L,
827L, 719L, 874L, 692L, 752L, 536L, 658L, 817L, 913L, 813L,
844L, 811L, 977L, 877L, 818L, 673L, 1419L, 809L, 818L, 709L,
577L, 802L, 508L, 536L, 663L, 782L, 634L, 665L, 583L, 685L,
908L, 1013L, 903L, 965L, 981L, 1030L, 1205L, 1197L, 956L,
936L, 901L, 707L, 565L, 384L, 341L, 529L, 510L, 597L, 610L,
587L, 715L, 777L, 638L, 619L, 617L, 677L, 1118L, 1173L, 1025L,
655L, 1006L, 1129L, 811L, 773L, 796L, 993L, 891L, 900L, 1072L,
1182L, 947L, 743L, 759L, 616L, 584L, 613L, 597L, 734L, 671L,
1119L, 906L, 825L, 1109L, 1085L, 913L), Y = c(0L, 23L, 50L,
35L, 38L, 38L, 43L, 173L, 128L, 134L, 115L, 103L, 104L, 122L,
168L, 186L, 158L, 136L, 122L, 91L, 87L, 73L, 105L, 97L, 96L,
84L, 121L, 108L, 83L, 106L, 108L, 107L, 96L, 151L, 128L,
135L, 148L, 133L, 114L, 150L, 175L, 172L, 182L, 185L, 181L,
224L, 451L, 369L, 399L, 377L, 325L, 259L, 245L, 268L, 284L,
338L, 375L, 383L, 307L, 318L, 341L, 290L, 401L, 333L, 336L,
404L, 406L, 333L, 372L, 372L, 388L, 236L, 162L, 264L, 378L,
390L, 350L, 327L, 341L, 359L, 462L, 413L, 421L, 400L, 424L,
283L, 377L, 459L, 478L, 482L, 411L, 416L, 522L, 557L, 502L,
479L, 631L, 533L, 514L, 442L, 477L, 432L, 378L, 365L, 443L,
407L, 384L, 451L, 381L, 435L, 603L, 612L, 685L, 567L, 603L,
576L, 564L, 643L, 671L, 722L, 695L, 463L, 328L, 228L, 160L,
235L, 282L, 346L, 332L, 340L, 396L, 433L, 354L, 356L, 355L,
367L, 462L, 445L, 454L, 355L, 566L, 628L, 491L, 517L, 429L,
569L, 595L, 520L, 601L, 646L, 630L, 590L, 513L, 465L, 390L,
356L, 356L, 417L, 420L, 443L, 450L, 482L, 540L, 611L, 572L
)), row.names = c(NA, -165L), class = c("tbl_df", "tbl",
"data.frame"))
Firstly I convert it into xts object and next use ts_plot() for visualization
#Create xts object
df.xts <- xts(df[, 2:3], order.by = df.w$week)
#plot
library(TSstudio)
ts_plot(df.xts,
slider = TRUE)
I tried the following codes, but it give me the "NULL" in the output
+ geom_vline(xintercept = as.Date("2020-03-01"))
or
+ geom_vline(xintercept = as.POSIXct("2020-03-01"))
Edit
You could use the add_segments function from plotly. You could also add multiple lines by specifying vectors like this:
library(xts)
library(TSstudio)
library(dplyr)
library(plotly)
#Create xts object
df.xts <- xts(df[, 2:3], order.by = df$week)
# plot
ts_plot(df.xts) %>%
add_segments(y = c(0, 0, 0),
x = as.Date(c("2020-03-01", "2020-06-01", "2020-08-01")),
yend = c(1500, 1500, 1500),
xend = as.Date(c("2020-03-01", "2020-06-01", "2020-08-01")),
color = c('red', 'green', 'purple'),
showlegend = FALSE)
Created on 2022-10-12 with reprex v2.0.2
Because you are using xts data format, you can use the function addEventLines to add some vertical lines. Here is a reproducible example:
library(xts)
library(rtweet)
#Create xts object
df.xts <- xts(df[, 2:3], order.by = df$week)
# plot
plot(df.xts)
addEventLines(xts('', as.Date("2020-03-01")), pos = 2, srt = 90, col = 'blue')
Created on 2022-10-11 with reprex v2.0.2

Multi-row x-axis labels with breaks in R

I would like to add 2-row x-axis labels on my line plot, but not sure how to also incorporate the continuous labels and breaks I have for my 1st x-axis (Column "CYR" - short for calendar year). I'd like to have the 2nd axis (WYR) start half-way between the first label and the second (WYR = 2010 starts between CYR = 2009 -> 2010). I also wasn't sure how to add 2 x-axis titles either, maybe at the beginning of each x-axis row?
My data:
> dput(wet_pivot)
structure(list(WYR = c("WR_2010", "WR_2011", "WR_2012", "WR_2013",
"WR_2014", "WR_2015", "WR_2016", "WR_2017", "WR_2018", "WR_2019",
"WR_2020", "WR_2021", "WR_2022"), CYR = c(2009, 2010, 2011, 2012,
2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021), Season = structure(c(2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("DRY",
"WET"), class = "factor"), N = c(59L, 63L, 69L, 70L, 72L, 71L,
71L, 72L, 71L, 68L, 70L, 48L, 72L), n_mean = c(0.00696806934430411,
0.000649730847004026, 0.00288256551918419, 0.01141088388474,
0.000536174103147671, 0.00349584646220785, 0.000482925207291882,
0.00245359625194744, 0.00292096956686587, 0.00252817293686805,
0.00196286772014134, 0.00501799463867351, 0.00132244297252478
), n_median = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), sd = c(0.030946706350869,
0.00248965525641742, 0.0100973832581282, 0.051577934580242, 0.00331468784320076,
0.0266064084754242, 0.00212505905295283, 0.00675243933898364,
0.0119729983336735, 0.00639785127193391, 0.00930625647382774,
0.0136275258272549, 0.00543420856675111), se = c(0.00402891799826298,
0.000313667078988821, 0.00121558209746373, 0.0061647423020683,
0.000390639708573979, 0.00315759975690469, 0.000252198110662322,
0.000795782607691024, 0.00142093348159893, 0.000775853428563995,
0.00111231039833223, 0.00196696392618855, 0.000640427621321956
)), row.names = c(NA, -13L), class = "data.frame")
My attempt:
years <- seq(2009,2021,1)
labs <- seq(2009,2021,by=1)
myplot <- ggplot(wet_pivot, aes(x = CYR, y = n_mean)) +
geom_errorbar(aes(ymin=n_mean-se, ymax=n_mean+se), width=.2, color = "black") +
geom_point(color = "black", shape = 1, size = 2) +
geom_line(color = "black") +
scale_y_continuous(limits = c(0, 0.04), expand = expansion(mult = c(0, 0.05))) +
scale_x_continuous(breaks= years, labels = labs)
myplot +
annotate(geom = "text",
x = 1:nrow(wet_pivot),
y = min(wet_pivot$n_mean),
label = labs,
vjust = 3.5) +
annotate(geom = "text",
x = 1:nrow(wet_pivot),
y = min(wet_pivot$n_mean),
label = wet_pivot$WYR,
vjust = 5)
You indeed can use text annotations to substitute for x-axis labels. A few recommendations:
Set y = -Inf to automatically place text as bottom, independent of whatever data is on the plot. vjust can indeed be used to place it further down.
You'd need coord_cartesian(clip = "off") to actually show the text.
You can place 'titles' with an extra annotation layer, with x = -Inf to place it on the left.
I used the above for the example below. Maybe the text is still to big, so you could set the 8.8 / .pt to something smaller. (The / .pt translates between mm, which geom_text() uses, to points, which is used in theme)
library(ggplot2)
# wet_pivot <- structure(...) # omitted for previty
ggplot(wet_pivot, aes(x = CYR, y = n_mean)) +
geom_errorbar(aes(ymin=n_mean-se, ymax=n_mean+se), width=.2, color = "black") +
geom_point(color = "black", shape = 1, size = 2) +
geom_line(color = "black") +
scale_y_continuous(limits = c(0, 0.04), expand = expansion(mult = c(0, 0.05))) +
scale_x_continuous(breaks= years, labels = ~ rep("", length(.x))) +
annotate(geom = "text",
x = wet_pivot$CYR,
y = -Inf,
label = labs,
size = 8.8 / .pt,
vjust = 2.5) +
annotate(geom = "text",
x = wet_pivot$CYR,
y = -Inf,
label = wet_pivot$WYR,
size = 8.8 / .pt,
vjust = 4) +
# Titles
annotate(geom = "text",
x = -Inf,
y = -Inf,
label = c("CYR", "WYR"),
vjust = c(2.5, 4), hjust = 1,
size = 8.8 / .pt
) +
coord_cartesian(clip = "off") +
theme(
# Make extra space between axis ticks and axis title
axis.text.x.bottom = element_text(margin = margin(t = 8.8, b = 8.8))
)
Created on 2022-05-19 by the reprex package (v2.0.1)

Non-linear regression line and its Computation failed in `stat_smooth()`: argument "p" is missing, with no default error

I have been trying to fit a non-linear regression line into my standard curve. However, I am getting the following error:
The main problem is that with the linear regression line I could use a simple command like:
stat_cor(label.y = c(825),
label.x = c(0.88),
aes(label = paste(..rr.label.., ..p.label.., sep = "~`,`~")))+
stat_regline_equation(label.x=0.88, label.y=750)+
And the equation for the linear regression line with an a, and b values appear. In this case after using the following:
stat_smooth(method= "nlm",
formula = y~a*x/(b+x),
method.args = list( start = c(a = 3.8, b = 1457.2)),
se=FALSE)+
I am getting the above error.
You may ask where I got the a, and b values? I got them from:
nls(y~a*x/(b+x))
That has shown:
I do not know where I am making mistakes.
This is the entire code for my graph
library(tidyverse)
library(tidyr)
library(dplyr)
library(readr)
library(ggplot2)
library(ggpubr)
ggplot(data = STD, aes(x = Absorbance, y = STD)) +
labs(title = "Quantifying PGD2 in cell culture lysates and its enzymatic reactions ",
caption = "PGD2 ELISA")+
geom_point(colour = "#69b3a2")+
stat_smooth(method= "nlm",
formula = y~a*x/(b+x),
method.args = list( start = c(a = 3.8, b = 1457.2)),
se=FALSE)+
xlab(expression(paste("%B/"~B[0])))+
ylab(expression(paste("Prostaglandin"~ D[2], ~~ " MOX Concentration (pg/ml) ")))+
theme(plot.background = element_rect(fill = "transparent"),
panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"))+
theme(legend.spacing.y = unit(0.01, "cm"))+
theme(legend.position = c(0.77, .91),
legend.background = element_rect(colour = NA, fill = NA))+
theme(plot.title = element_text(size = 12, face = "bold.italic"),
plot.caption = element_text(hjust = 0))
That gives the following outcome
And this is DataUsed
So, I think I have found a solution to my problem. I installed the install.packages(drc) in which the four parametric function is included. I set up my data model <- drm(STD ~ Absorbance, fct = LL.4(), data = STD), then plot(model) , and I got
I know it requires some alternations to make it look more professional, but it is just a cosmetic thing that I should be fine to do. Thank you #stefan for your time.

Connect observations (dots and lines) without using ggpaired

I created a bar chart using geom_bar with "Group" on the x-axis (Female, Male), and "Values" on the y-axis. Group is further subdivided into "Session" such that there is "Session 1" and "Session 2" for both Male and Female (i.e. four bars in total).
Since all participants participated in Session 1 and 2, I overlayed a dotplot (geom_dot) over each of the four bars, to represent the individual data.
I am now trying to connect the observations for all participants ("PID"), between session 1 and 2. In other words, there should be lines connecting several sets of two-points on the "Male" portion of the x-axis (i.e. per participant), and "Female portion".
I tried this with "geom_line" (below) but to no avail (instead, it created a single vertical line in the middle of "Male" and another in the middle of "Female"). I'm not too sure how to fix this.
See code below:
ggplot(data_foo, aes(x=factor(Group),y=Values, colour = factor(Session), fill = factor(Session))) +
geom_bar(stat = "summary", fun.y = "mean", position = "dodge") +
geom_dotplot(binaxis = "y", stackdir = "center", dotsize = 1.0, position = "dodge", fill = "black") +
geom_line(aes(group = PID), colour="dark grey") +
labs(title='My Data',x='Group',y='Values') +
theme_light()
Sample data (.txt)
data_foo <- readr::read_csv("PID,Group,Session,Values
P1,F,1,14
P2,F,1,13
P3,F,1,16
P4,M,1,18
P5,F,1,20
P6,M,1,27
P7,M,1,19
P8,M,1,11
P9,F,1,28
P10,F,1,20
P11,F,1,24
P12,M,1,10
P1,F,2,26
P2,F,2,21
P3,F,2,19
P4,M,2,13
P5,F,2,26
P6,M,2,15
P7,M,2,23
P8,M,2,23
P9,F,2,30
P10,F,2,21
P11,F,2,11
P12,M,2,19")
The trouble you have is that you want to dodge by several groups. Your geom_line does not know how to split the Group variable by session. Here are two ways to address this problem. Method 1 is probably the most "ggploty way", and a neat way of adding another grouping without making the visualisation too overcrowded. for method 2 you need to change your x variable
1) Use facet
2) Use interaction to split session for each Group. Define levels for the right bar order
I have also used geom_point instead, because geom_dot is more a specific type of histogram.
I would generally recommend to use boxplots for such plots of values like that, because bars are more appropriate for specific measures such as counts.
Method 1: Facets
library(ggplot2)
ggplot(data_foo, aes(x = Session, y = Values, fill = as.character(Session))) +
geom_bar(stat = "summary", fun.y = "mean", position = "dodge") +
geom_line(aes(group = PID)) +
geom_point(aes(group = PID), shape = 21, color = 'black') +
facet_wrap(~Group)
Created on 2020-01-20 by the reprex package (v0.3.0)
Method 2: create an interaction term in your x variable. note that you need to order the factor levels manually.
data_foo <- data_foo %>% mutate(new_x = factor(interaction(Group,Session), levels = c('F.1','F.2','M.1','M.2')))
ggplot(data_foo, aes(x = new_x, y = Values, fill = as.character(Session))) +
geom_bar(stat = "summary", fun.y = "mean", position = "dodge") +
geom_line(aes(group = PID)) +
geom_point(aes(group = PID), shape = 21, color = 'black')
Created on 2020-01-20 by the reprex package (v0.3.0)
But everything gets visually not very compelling.
I suggest doing a few visualization tips to have a more informative chart. For example, I feel like having a differentiation of colors for PID will help us track the changes of each participant for different levels of other variables. Something like:
library(ggplot2)
ggplot(data_foo, aes(x = factor(Session), y = Values, fill = factor(Session))) +
geom_bar(stat = "summary", fun.y = "mean", position = "dodge") +
geom_line(aes(group = factor(PID), colour=factor(PID)), size=2, alpha=0.7) +
geom_point(aes(group = factor(PID), colour=factor(PID)), shape = 21, size=2,show.legend = F) +
theme_bw() +
labs(x='Session',fill='Session',colour='PID')+
theme(legend.position="right") +
facet_wrap(~Group)+
scale_colour_discrete(breaks=paste0('P',1:12))
And we have the following plot:
Hope it helps.

Legend not showing. Error in strwidth(legend, units = "user", cex = cex, font = text.font) : plot.new has not been called yet

I have the code below that is a combination of two boxplots and dot plots in one. It is a representation of barring density in 4 different species. The grey depicts the males and the tan the females.
data<-read.csv("C:/Users/Jeremy/Documents/A_Trogon rufus/Black-and-White/BARDATA_boxplots_M.csv")
datF<-read.csv("C:/Users/Jeremy/Documents/A_Trogon rufus/FEMALES_BW&Morphom.csv")
cleandataM<-subset(data, data$Age=="Adult" & data$White!="NA", select=(OTU:Density))
cleandatF<-subset(datF, datF$Age=="Adult", select=(OTU:Density))
dataM<- as.data.frame(cleandataM)
dataF<- as.data.frame(cleandatF)
library(ggplot2)
ggplot(dataM, aes(factor(OTU), Density))+
geom_boxplot(data=dataF,aes(factor(OTU),Density), fill="AntiqueWhite")+
geom_boxplot(fill="lightgrey", alpha=0.5)+
geom_point(data=dataF,position = position_jitter(width = 0.1), colour="tan")+
geom_point(data=dataM, position = position_jitter(width = 0.1), color="DimGrey")+ scale_x_discrete(name="",limits=order)+
scale_y_continuous(name="Bar Density (bars/cm)")+
theme(panel.background = element_blank(),panel.grid.minor=element_blank(),
panel.grid.major=element_blank(),axis.line = element_line(colour = "black"),
axis.title.y = element_text(colour="black", size=14),
axis.text.y = element_text(colour="black", size=12),
axis.text.x = element_text(colour="black", size=14))
This works just fine.
However, when I try to add a legend as:
legend("topright", inset=.01, bty="n", cex=.75, title="Sex",
c("Male", "Female"), fill=c("lightgrey", "black")
It returns the following Error:
Error in strwidth(legend, units = "user", cex = cex, font = text.font) :
plot.new has not been called yet
Please, is there someone who could suggest how to correct this?