I have a line graph with several lines, in which I want to highlight certain values with a different geom_point shape.
The dput of a similar data to mine is:
structure(list(Iso = structure(1:9, .Label = c("a", "b", "c",
"d", "e", "f", "g", "h", "i"), class = "factor"), z1 = c(342.6,
8.94, 6.91, 3.96, 1.89, 4.38, 1.43, 5.18, 189.1), z2 = c(187.34,
2.8, 8.42, 8.24, 2.36, 2.34, 7.6, 0.5, 136.01)), row.names = c(NA,
-9L), spec = structure(list(cols = list(Iso = structure(list(), class = c("collector_character",
"collector")), z1 = structure(list(), class = c("collector_double",
"collector")), z2 = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))
This is the code:
library(readr)
library(ggplot2)
library(RColorBrewer)
y <- read_csv("dummy.csv")
y$Iso <- factor(y$Iso, levels=y$Iso)
##
plot <- ggplot(y,aes(Iso,group=1)) +theme_bw() + ggtitle('') +
theme(plot.title = element_text(hjust = 0.5)) +
geom_point(aes(y=z1, colour='z1'), na.rm=FALSE, size=3, shape=16) +
geom_point(aes(y=z2, colour='z2'), na.rm=FALSE, size=3,shape=16) +
geom_line(aes(y=z1, colour='z1'), na.rm=FALSE, linetype=1,size=1) +
geom_line(aes(y=z2, colour='z2'), na.rm=FALSE,linetype=3, size=2) +
xlab('') +ylab('ZZ/CI') + scale_y_log10(limits=c(0.1,2000), breaks=c(1e-1,1,1e1,1e2,1e3))
##
plot + theme(axis.text.x = element_text(angle = 90, vjust = 0.5,size=19, face='bold'),
axis.text.y = element_text(size=12),
axis.title.y = element_text(size=15)) +
scale_colour_manual(name='',breaks=c('z1','z2'),values= c('brown','wheat'),labels= c('z1','z2')) +
guides(colour = guide_legend(override.aes = list (size = c(.75,.75),linetype=c(1,3),shape=c(16,16))))
I use the guide for every cosmetic element in order to make the legend more legible.
The data
# A tibble: 9 x 3
Iso z1 z2
<fct> <dbl> <dbl>
1 a 343.6 187.34
2 b 8.94 2.8
3 c 6.91 8.42
4 d 3.96 8.24
5 e 1.89 2.36
6 f 4.38 2.34
7 g 1.43 7.6
8 h 5.18 0.5
9 i 189.1 136.01
For example, in the case of these data, I want to change the shape from 16 to 13, in z1 for '342.6','1.43', and '5.18', and in z2 for '187.34,'2.36','7.6' and '0.5'.
How can I proceed?
Thank you for your time.
I think you should consider reformatting your data to long format, as it saves a lot of duplication. Secondly, you need to specify a new column in your data, which you map to shape. If there is no pattern like any value larger than 100 you need to cherry-pick the values you want to highlight by hand.
The following code should do what you want:
library(tidyverse)
y <- structure(list(Iso = structure(1:9, .Label = c("a", "b", "c",
"d", "e", "f", "g", "h", "i"),
class = "factor"),
z1 = c(342.6, 8.94, 6.91, 3.96, 1.89, 4.38, 1.43, 5.18, 189.1),
z2 = c(187.34, 2.8, 8.42, 8.24, 2.36, 2.34, 7.6, 0.5, 136.01)),
row.names = c(NA, -9L),
class = c("data.frame"))
## transform to long format
y.long <- y %>% gather(type, value, -Iso)
## add a new column which 'marks' the special rows
## NOTE: since we moved to long format rows corresponding to z2 are starting now at row 10
y.long <- y.long %>% mutate(highlight = ifelse(type == "z1",
ifelse(row_number() %in% c(1, 7, 8),
"special", "normal"),
ifelse(row_number() %in% c(10, 14, 16, 17),
"special", "normal")))
## in your ggplot you can now map the columns to the graphical elements like so:
ggplot(y.long, aes(Iso, value,
color = type, linetype = type, shape = highlight,
group = type)) +
geom_point(size = 3) +
geom_line(aes(size = type)) +
scale_y_log10(limits = c(0.1, 2000), breaks = c(1e-1, 1, 1e1, 1e2, 1e3)) +
scale_color_manual("", values = c(z1 = "brown", z2 = "wheat")) +
scale_size_manual("", values = c(z1 = 1, z2 = 2), guide = "none") +
scale_shape_manual("", values = c(normal = 16, special = 13), guide = "none") +
scale_linetype_manual("", values = c(z1 = "solid", z2 = "dotted"), guide = "none") +
labs(x = "", y = "ZZ/CI") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, size = 19, face = "bold"),
axis.text.y = element_text(size = 12),
axis.title.y = element_text(size = 15))
This results in the following plot:
You can adapt the mutate satement to include/exclude other rows and the scale_* functions to show/hide legends.
Theoretically, you could use something like this in your mutate
mutate(highlight = ifelse(value %in% c(343.6, 1.43, 5.18, 187.34,
2.36, 7.6, 0.5),
"special", "normal"))
but due to floating point issues (cf. for instance this article), i would not do this and rather select by row number (as I did) or any other suitable criterion, or use all.equal to make proper floating point comparisons.
Related
I'm trying to show the values of each bar on the plot, so that there are twelve unique values in total across the plot, by or on each bar. Each bar is made up of several stacked variables, and I've made an additional data frame with the sum totals of each bar. But instead they duplicate, when using geom_text. Is there any way to fix this? I've never posted here before, so I don't know how much I should provide of my code (it is extremely messy because I've Frankensteined the code from too many google searches)
The following, Finx, is the basis for my plot.
Finx:
AROID Marktäcke Nutrient Area.km2 Konc.KgM3 Markan.
<chr> <chr> <chr> <dbl> <dbl> <chr>
1 646432-143677 ExtensivVall N 5.36 952. Jordbruk
2 645785-143513 ExtensivVall N 5.86 1040. Jordbruk
3 645157-143904 ExtensivVall N 3.09 549. Jordbruk
4 646432-143677 Grönträda N 2.87 3523. Jordbruk
5 645785-143513 Grönträda N 0.956 1174. Jordbruk
6 645157-143904 Grönträda N 0.100 123. Jordbruk
7 646432-143677 Havre N 1.07 1712. Jordbruk
8 645785-143513 Havre N 0.203 325. Jordbruk
9 645157-143904 Havre N 0.0173 27.7 Jordbruk
10 646432-143677 Höstraps N 1.16 2146. Jordbruk
# … with 69 more rows
Which I work with to present the data.
Finx1 <- Finx %>%
group_by(AROID, Nutrient) %>%
mutate(AROID = recode(AROID, "645157-143904" = "Dis. Utl. Bonderydssjön", "646432-143677" = "Inloppet Tåkern", "645785-143513" = "Nära S:t Åby" )) %>%
ungroup()
Fa <- Finx1 %>%
group_by(AROID, Nutrient, Markan.) %>%
summarize(Konc.KgM3) %>%
summarize_all(sum) %>%
mutate(Tot.kg = Konc.KgM3) %>%
select(-Konc.KgM3)
Fum <- left_join(Finx1, Fa, by = c("AROID", "Nutrient"))
Fum <- Fum[!duplicated(Fum[c('Tot.kg')]), ]
Fum[,'Tot.kg']=round(Fum[,'Tot.kg'], 0)
Fum <- Fum %>%
select(-Markan..x)
Then I make the ggplot,
ggplot(Finx1) +
aes(x = AROID, fill = Marktäcke, y = Konc.KgM3) +
geom_col(alpha = 0.8) +
scale_fill_manual(values = wes_palette("Darjeeling1", type = "continuous", n = 17)) +
theme_light() +
coord_flip() +
geom_text(aes(AROID, Tot.kg, label = Tot.kg, fill = NULL), size = 3, data = Fum2, hjust = 1) +
facet_grid(Markan. ~ Nutrient, scales = "free_x") +
ylab("Total mängd i Kg/år") +
xlab("Delavrinningsområde") +
labs(title='Utlakning av näringsämnen 2007') +
theme(plot.title = element_text(hjust = 0.5, color = "#5A5A5A"), axis.title.x = element_text(color = "#383838"), axis.title.y = element_text(color = "#383838"))
I probably make some mistake here, like showing too little data or something. Idk, but I have no idea what I'm supposed to do.
In principle your ggplot2 code was fine but you messed up the data wrangling, which could be simplifeid without the need of a join:
library(dplyr)
library(ggplot2)
library(wesanderson)
Finx1 <- Finx %>%
mutate(AROID = recode(AROID,
"645157-143904" = "Dis. Utl. Bonderydssjön",
"646432-143677" = "Inloppet Tåkern",
"645785-143513" = "Nära S:t Åby"
))
Fum <- Finx1 %>%
group_by(AROID, Nutrient, Markan.) %>%
summarize(Tot.kg = sum(Konc.KgM3))
ggplot(Finx1) +
aes(x = Konc.KgM3, y = AROID) +
geom_col(aes(fill = Marktäcke), alpha = 0.8) +
geom_text(aes(x = Tot.kg, label = Tot.kg), size = 3, data = Fum, hjust = -.1) +
scale_x_continuous(expand = c(0, 0, 0, 1500)) +
scale_fill_manual(values = wes_palette("Darjeeling1",
type = "continuous", n = 17
)) +
facet_grid(Markan. ~ Nutrient, scales = "free_x") +
theme_light() +
theme(
plot.title = element_text(hjust = 0.5, color = "#5A5A5A"),
axis.title = element_text(color = "#383838")
) +
labs(
x = "Total mängd i Kg/år",
y = "Delavrinningsområde",
title = "Utlakning av näringsämnen 2007"
)
DATA
Finx <- structure(list(AROID = c(
"646432-143677", "645785-143513", "645157-143904",
"646432-143677", "645785-143513", "645157-143904", "646432-143677",
"645785-143513", "645157-143904", "646432-143677"
), Marktäcke = c(
"ExtensivVall",
"ExtensivVall", "ExtensivVall", "Grönträda", "Grönträda",
"Grönträda", "Havre", "Havre", "Havre", "Höstraps"
), Nutrient = c(
"N",
"N", "N", "N", "N", "N", "N", "N", "N", "N"
), Area.km2 = c(
5.36,
5.86, 3.09, 2.87, 0.956, 0.1, 1.07, 0.203, 0.0173, 1.16
), Konc.KgM3 = c(
952,
1040, 549, 3523, 1174, 123, 1712, 325, 27.7, 2146
), Markan. = c(
"Jordbruk",
"Jordbruk", "Jordbruk", "Jordbruk", "Jordbruk", "Jordbruk", "Jordbruk",
"Jordbruk", "Jordbruk", "Jordbruk"
)), class = "data.frame", row.names = c(
"1",
"2", "3", "4", "5", "6", "7", "8", "9", "10"
))
I am using facet_grid() to display a 2x2 of different combinations of model types for racial groups and levels of participation in a program.
By using scales = "free" I am able to separate out the y axes for each row and only display the relevant coefficients. But, how can I then specify the model/variable order within each panel row? Typically, I would do something like:
model_order <- c("White", "Black", "Hispanic")
And then pass that through to scale_x_discrete(). (And would have High, then Medium, then Low in that order).
But that does not seem to work in this case because of using scales = "free". Is there a workaround for controlling the order?
Code:
mylabels <- c("1" = "Linear",
"2" = "Logit",
"3" = "Race",
"4" = "Level")
ggplot(dx, aes(x = var, y = coef,
ymin = ci_lower, ymax = ci_upper)) +
geom_point(size = 2) +
geom_errorbar(width = 0.1,
size = 1) +
facet_grid(effect~model,
scales = "free",
labeller = as_labeller(mylabels)) +
scale_y_continuous(breaks = seq(-3, 3, by = 1)) +
coord_flip() +
theme_bw(base_size = 15) +
theme(legend.position = "none")
Data:
structure(list(var = c("White", "Black", "Hispanic", "White",
"Black", "Hispanic", "High", "Medium", "Low", "High", "Medium",
"Low"), coef = c(1.64, 1.2, 0.4, 1.45, 0.17, 0.6, 1.04, 0.05,
-0.74, -0.99, -0.45, -0.3045), ci_lower = c(1.3, 0.86, 0.06,
1.11, -0.17, 0.26, 0.7, -0.29, -1.08, -1.33, -0.79, -0.6445),
ci_upper = c(1.98, 1.54, 0.74, 1.79, 0.51, 0.94, 1.38, 0.39,
-0.4, -0.65, -0.11, 0.0355), model = c(1, 1, 1, 2, 2, 2,
1, 1, 1, 2, 2, 2), effect = c(3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 4)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -12L), spec = structure(list(cols = list(
var = structure(list(), class = c("collector_character",
"collector")), coef = structure(list(), class = c("collector_double",
"collector")), ci_lower = structure(list(), class = c("collector_double",
"collector")), ci_upper = structure(list(), class = c("collector_double",
"collector")), model = structure(list(), class = c("collector_double",
"collector")), effect = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1L), class = "col_spec"))
You can define your variable as a factor, and then reorder their levels:
library(dplyr)
library(ggplot2)
mylabels <- c("1" = "Linear",
"2" = "Logit",
"3" = "Race",
"4" = "Level")
dx %>%
mutate(var = forcats::fct_relevel(var,"High","Medium")) %>%
ggplot(aes(x = var, y = coef,
ymin = ci_lower, ymax = ci_upper)) +
geom_point(size = 2) +
geom_errorbar(width = 0.1,
size = 1) +
facet_grid(effect~model,
scales = "free",
labeller = as_labeller(mylabels)) +
scale_y_continuous(breaks = seq(-3, 3, by = 1)) +
coord_flip() +
theme_bw(base_size = 15) +
theme(legend.position = "none")
The dput(Q_Sheet) is below. How can properly introduce a second y-axis that is different in scale from the primary axis?
structure(list(Amino_acids = c(4, 12, 20, 28, 32), Protein_length_Ang = c(7,
24, 40, 56, 64), length_no_ratio = c(1.75, 2, 2, 2, 2), Corrected_aa = c(1.24459201924769e-12,
3.71007650662474e-09, 1.10594599229843e-05, 0.0319159404863842,
0.642857142857143), aa_frequency = c(3.99735380592756, 6.96840672963299,
4.58228895300999, 3.12310921028256, 4.67560843680985), T_degC = c(50.3857804818545,
52.8464583426248, 60.0760389538482, 58.1895053328481, 67.628202708438
)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"
), na.action = structure(c(`2` = 2L, `4` = 4L, `6` = 6L), class = "omit"))
`
ggplot(data = Q_Sheet, aes(x = T_degC))+
geom_line(aes(y = Amino_acids), color="red")+
geom_line(aes(y = Corrected_aa), color = "blue") +
scale_y_continuous(name = "Amino_acids", sec.axis = sec_axis(~.*10, name = "Corrected_aa"))
The output is as follows:
<ScaleContinuousPosition>
Range:
Limits: 0 -- 1
You can use the below formula to keep the secondary Y-axis at the same level as Corrected_aa.
library(ggplot2)
ggplot(data=Q_Sheet, aes(x=T_degC))+
geom_line(aes(y=Amino_acids),color="red")+
geom_line(aes(y=Corrected_aa),color="blue")+
scale_y_continuous(name="Amino_acids",
sec.axis=sec_axis(~{
a <- min(Q_Sheet$Corrected_aa)
b <- max(Q_Sheet$Corrected_aa)
((((b-a) * (. - min(.)))/diff(range(.))) + a)
},name="Corrected_aa"))
There are two issues - 1) scale_y_continuous typo and 2) there is a missing + connecting the last expression
ggplot(data=Q_Sheet, aes(x=T_degC))+
geom_line(aes(y=Amino_acids),color="red")+
geom_line(aes(y=Corrected_aa),color="blue") +
scale_y_continuous(name="Amino_acids",
sec.axis=sec_axis(~.*10,name="Corrected_aa"))
-ouptut
We could define a coefficient and then color the lines to indicate wich lines belongs to which y-scale:
library(ggplot2)
value used to transform the data
coeff <- 0.01
# colors
Amino_acidsColor = "red"
Corrected_aaColor = "blue"
ggplot(data=Q_Sheet, aes(x=T_degC))+
geom_line(aes(y=Amino_acids), size = 2, color=Amino_acidsColor)+
geom_line(aes(y=Corrected_aa/coeff), size = 2, color=Corrected_aaColor) +
scale_y_continuous(name="Amino_acids",
sec.axis=sec_axis(~.*coeff,name="Corrected_aa")) +
theme_bw() +
theme(
axis.title.y = element_text(color = Amino_acidsColor, size=13),
axis.title.y.right = element_text(color = Corrected_aaColor, size=13)
)
I'm attempting to make a stacked bar chart mapping a variable to fill on a log10 scale. I'd like to pass it through ggplotly, in order to have data inspection possible via tooltip.
There are two problems. First, when I log transform the scale of VAR.B in scale_fill_gradientn, the tooltips display transformed data, while the graph displays data in its original scale, which is unhelpful.
However, when I include the text aesthetic in ggplot to fix this issue, it breaks the order of the fill. I haven't been able to find a way to fix both issues.
I have tried log10 transforming VAR.B in the dataframe itself. In this case, the tooltips match the displayed data, but I don't think this will be easily approachable for my audience. Also, leaving the dataset in a linear scale loses an important part of the story.
Dataset
a<-structure(list(VAR.A = c("A", "A", "A", "A", "A", "A", "A", "A",
"A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B"),
VAR.B = c(1, 2, 3, 5, 8, 9, 10, 12, 13, 15, 1, 10, 30, 35,
40, 60, 80, 100, 140, 160), rel.freq = c(3.076923077, 4.615384615,
7.692307692, 12.30769231, 15.38461538, 6.153846154, 30.76923077,
3.076923077, 7.692307692, 9.230769231, 1.754385965, 3.50877193,
26.31578947, 1.754385965, 17.54385965, 35.0877193, 3.50877193,
5.263157895, 3.50877193, 1.754385965)), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -20L), spec = structure(list(
cols = list(VAR.A = structure(list(), class = c("collector_character",
"collector")), VAR.B = structure(list(), class = c("collector_double",
"collector")), counts = structure(list(), class = c("collector_double",
"collector")), rel.freq = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
Dependencies
library(ggplot2)
library(viridis)
library(plotly)
library(scales)
This graph looks like it should, but the values displayed in hover text for VAR.B don't match the original scale
f <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B)) +
geom_bar(width = 1, size = 1, stat = "identity") +
scale_fill_gradientn(colors = viridis(10, option = 'inferno'), limits = c(0.1, 160), breaks = c(0.1,0.3, 1, 3, 10, 30, 100),
trans = "log10", guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), oob = squish) +
theme_classic()
f<- ggplotly(f)
f
This graph looks disordered, but the values displayed in hover text for VAR.B do match the original scale.
g <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B, text = paste0('VAR.B:', VAR.B))) + geom_bar(width = 1, size = 1, stat = "identity") +
scale_fill_gradientn(colors = viridis(10, option = 'inferno'), limits = c(0.1, 160), breaks = c(0.1,0.3, 1, 3, 10, 30, 100),
trans = "log10", guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), oob = squish) +
theme_classic()
g <- ggplotly(g, tooltip = c('VAR.A','VAR.B','text'))
g
If I leave the paste0() function out of the text aesthetic and only call VAR.B itself, then the tooltips display data in the original scale and the order of the fill is preserved. But the tooltip doesn't give a label for the data in this case.
h <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B, text = VAR.B)) +
geom_bar(width = 1, size = 1, stat = "identity") +
scale_fill_gradientn(colors = viridis(10, option = 'inferno'), limits = c(0.1, 160), breaks = c(0.1,0.3, 1, 3, 10, 30, 100),
trans = "log10", guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), oob = squish) +
theme_classic()
h <- ggplotly(h, tooltip = c('VAR.A','VAR.B','text'))
h
It seems to me that the paste0() function in the text aesthetic is bugged. If anyone can think of another way to fix all of these problems at once, I would greatly appreciate it.
This happens, because text = paste0('VAR.B:', VAR.B))) creates a factor, that is ordered alphabetically.
i <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B,
text = factor(paste0('VAR.Bt:', VAR.B)[order(VAR.A,VAR.B)],
levels=unique(paste0('VAR.Bt:', VAR.B)[order(VAR.A,VAR.B)]),
ordered = T) #makes the factor specifically ordered
)
) +
geom_bar(width = 1, size = 1, stat = "identity",
position = position_stack(reverse = T) #has to be reversed, so high values of VAR.B appear on top
) +
scale_fill_gradientn(colors = viridis(10, option = 'inferno'),
limits = c(0.1, 160),
breaks = c(0.1,0.3, 1, 3, 10, 30, 100),
trans = "log10",
guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE),
oob = squish) +
theme_classic()
i <- ggplotly(i, tooltip = c('VAR.A','VAR.B','text'))
i
Hope this helps :-)
I edit the t, so it's more obvious which call produces what
I have a loop of 4 graphs with a character list like 'a, b, c, d', so in the title of each graph I want 'a', 'b', 'c' or 'd'. However, when I run my code, 'a' appears in all titles.
This is the dput of the data I am using.
structure(list(Point = c(5, 6, 7, 8), La = c(535, 565, 532, 587
), Ce = c(45, 46, 58, 43), Pr = c(56, 54, 43, 50), Nd = c(23,
28, 18, 26)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -4L), spec = structure(list(cols = list(
Point = structure(list(), class = c("collector_double", "collector"
)), La = structure(list(), class = c("collector_double",
"collector")), Ce = structure(list(), class = c("collector_double",
"collector")), Pr = structure(list(), class = c("collector_double",
"collector")), Nd = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
and the code I came up so far. ONLY the cols do not cycle through the title. The rest of the code works perfectly. I am still a beginner, so thank you for your time and patience.
acq <- select(X1, La:Nd)
##loop##
gg <- for (ii in acq){
cols <- names(X1)[2:5]
m <-mean(ii)
sds <- sd(ii)
m1 <- mean(ii)+1
m2 <-mean(ii)-1
##plot##
g <- ggplot(X1,aes_string(x="Point",y="ii")) +
ggtitle(paste(cols,"\n",m,"\n",sds,"\n")) +
theme(plot.title = element_text(hjust = 0.5)) +
geom_line() + geom_hline(aes(yintercept=mean(ii))) + ylab('') + xlab('')+
geom_hline(aes(yintercept=m1),linetype=2) +
geom_text(x=8,y=m1,label="10%",vjust=-1) +
geom_hline(aes(yintercept=m2),linetype=2) +
geom_text(x=8,y=m2,label="10%",vjust=-1)
print(g)
}
My data:
~Point, ~La, ~Ce, ~Pr, ~Nd,
5, 535, 45, 56, 23,
6, 565, 46, 54, 28,
7, 532, 58, 43, 18,
8, 587, 43, 50, 26
They way you setup the for-loop is not really recommended. It's better to loop through column names then extract that column from the acq data frame accordingly
library(tidyverse)
acq <- select(X1, La:Nd)
## loop ##
for (ii in seq_along(colnames(acq))) {
current_col <- colnames(acq)[ii]
print(paste0('Plot col: ', current_col))
# calculate mean and stdev
m <- mean(acq[[current_col]])
sds <- sd(acq[[current_col]])
m1 <- m + 1
m2 <- m - 1
## plot ##
g <- ggplot(X1, aes_string(x = "Point", y = current_col)) +
ggtitle(paste("column = ", current_col, "\n",
"mean = ", formatC(m, digits = 3), "\n",
"sd = ", formatC(sds, digits = 3), "\n")) +
theme_classic(base_size = 12) +
theme(plot.title = element_text(hjust = 0.5)) +
geom_line() +
geom_hline(aes(yintercept = m)) +
ylab("") + xlab("") +
geom_hline(aes(yintercept = m1), linetype = 2) +
geom_text(x = 8, y = m1, label = "10%", vjust = -1, check_overlap = TRUE) +
geom_hline(aes(yintercept = m2), linetype = 2) +
geom_text(x = 8, y = m2, label = "10%", vjust = 2, check_overlap = TRUE)
print(g)
}
Example output:
#> [1] "Plot col: La"
#> [1] "Plot col: Ce"
Another (preferable) way is to use the new tidy evaluation approach (more explanation here)
generate_plot2 <- function(df, .x.variable, .y.variable) {
x.variable <- rlang::sym(.x.variable)
y.variable <- rlang::sym(.y.variable)
sum_df <- df %>%
summarise_at(vars(!!y.variable), funs(mean, sd)) %>%
mutate(m1 = mean + 1,
m2 = mean - 1)
print(sum_df)
g <- ggplot(df, aes(x = !! x.variable, y = !! y.variable)) +
ggtitle(paste("column = ", .y.variable, "\n",
"mean = ", formatC(sum_df$mean, digits = 3), "\n",
"sd = ", formatC(sum_df$sd, digits = 3), "\n")) +
geom_line() +
geom_hline(aes(yintercept = sum_df$mean)) +
ylab("") + xlab("") +
geom_hline(aes(yintercept = sum_df$m1), linetype = 2) +
geom_text(x = 8, y = sum_df$m1, label = "10%", vjust = -1, check_overlap = TRUE) +
geom_hline(aes(yintercept = sum_df$m2), linetype = 2) +
geom_text(x = 8, y = sum_df$m2, label = "10%", vjust = 2, check_overlap = TRUE) +
theme_classic(base_size = 12) +
theme(plot.title = element_text(hjust = 0.5))
return(g)
}
plot_list <- names(X1)[-1] %>%
map(~ generate_plot2(X1, "Point", .x))
#> mean sd m1 m2
#> 1 554.75 26.15817 555.75 553.75
#> mean sd m1 m2
#> 1 48 6.78233 49 47
#> mean sd m1 m2
#> 1 50.75 5.737305 51.75 49.75
#> mean sd m1 m2
#> 1 23.75 4.349329 24.75 22.75
plot_list[[1]]
plot_list[[2]]
# bonus: combine all plots
library(cowplot)
plot_grid(plotlist = plot_list,
labels = 'AUTO',
nrow = 2,
align = 'hv',
axis = 'tblr')
Created on 2019-03-16 by the reprex package (v0.2.1.9000)