ggplot - legend as y-axis label - r

I have the following graph
Is it possible to add the legend labels (HPD and Quantile) under the respective boxplots? Also can i get rid of the white bar in the middle?
My code isthe following:
p <- ggplot(Results.Baseline,aes(x=Inference, y=Results, fill=Method)) +
scale_y_continuous(limits = c(0, 1))+
geom_boxplot()+facet_wrap(~Method)+ facet_wrap(~Model)+
geom_hline(yintercept=0.95, linetype="dashed", color = "red")
I basically want something like this just under all boxplots:
Here is my data:
data <- structure(list(Results = c(0.234375, 0.203125, 0.234375, 0.203125,
0.21875, 0.203125), Model = c("Baseline 1", "Baseline 1", "Baseline 1",
"Baseline 1", "Baseline 1", "Baseline 1"), Method = c("Quantile",
"Quantile", "Quantile", "Quantile", "Quantile", "Quantile"),
Inference = c("HMDM", "HMDM", "HMDM", "HMDM", "HMDM", "HMDM"
)), .Names = c("Results", "Model", "Method", "Inference"), row.names = c("1:nrow(transitions)",
"V2", "V3", "V4", "V5", "V6"), class = "data.frame")

I added more data so that I can replicate your graph better. You can
use geom_text to add the Method labels to the graph. You have to
only keep one label per box plot which is why I created the datalabs
dataframe. Also you did not need two facet_wraps in your plot. Does
this help answer your question?
data <- structure(list(Results = c(0.234375, 0.203125, 0.234375, 0.203125,
0.21875, 0.203125), Model = c("Baseline 1", "Baseline 1", "Baseline
1",
"Baseline 1", "Baseline 1", "Baseline 1"), Method = c("Quantile",
"Quantile", "Quantile", "Quantile", "Quantile", "Quantile"),
Inference = c("HMDM", "HMDM", "HMDM", "HMDM", "HMDM", "HMDM"
)), .Names = c("Results", "Model", "Method", "Inference"), row.names = c("1:nrow(transitions)",
"V2", "V3", "V4", "V5", "V6"), class = "data.frame")
data2 <- structure(list(Results = c(0.234375, 0.203125, 0.234375, 0.203125,
0.21875, 0.203125), Model = c("Baseline 2", "Baseline 2", "Baseline 2",
"Baseline 2", "Baseline 2", "Baseline 2"), Method = c("HPD",
"HPD", "HPD", "HPD", "HPD", "HPD"),
Inference = c("Eco. Inf.", "Eco. Inf.", "Eco. Inf.", "Eco. Inf.",
"Eco. Inf.", "Eco. Inf."
)), .Names = c("Results", "Model", "Method", "Inference"), row.names = c("1:nrow(transitions)",
"V2", "V3", "V4", "V5", "V6"), class = "data.frame")
data3 <- rbind(data,data2)
data4 <- mutate(data3, Method = ifelse(Method == "Quantile",
"HPD","Quantile"),
Inference = ifelse(Inference == "HMDM","Eco. Inf.",
"HMDM"))
data5 <- rbind(data3,data4)
datalabs <- data5 %>%
group_by(Method,Model) %>%
arrange(Method,Model) %>%
filter(row_number()==1)
ggplot(data5,aes(x=Inference, y=Results, fill=Method)) +
scale_y_continuous(limits = c(0, 1))+
geom_boxplot()+
facet_wrap(~Model)+
geom_hline(yintercept=0.95, linetype="dashed", color = "red")+
geom_text(data = datalabs, aes(label=Method) ,
nudge_y = -.1)+
theme_bw() +
theme(panel.grid = element_blank()) +
theme(panel.spacing = unit(0, "lines"),
strip.background = element_blank(),
panel.border = element_rect(fill = NA, color="white"))

Related

Free axis along particular facets in facet_grid ggplot

I am trying to do 2 things:
First and most important is to somehow get the y axis to vary by the outcome_type2 variable, since they all have fairly different ranges. So the "C" have their own axis range, the "Z" have their own axis range, and the "SS" have their own axis range.
Then the secondary thing would be to somehow adjust the spacing of columns, so that there's a bit of space by those same groups--the 3 "C" columns would be close together, with a bit of extra white space between them and the "Z", then same between "Z" and "SS". Just to differentiate a little more between those three groups.
I tried tinkering with faceting on outcome_type2 instead of outcome_type but to no avail.
This is current base code, which technically works fine, but as you'll see, having them all use the same Y axis really swamps the "Z" and "SS" panels.
ggplot(dtest, aes(x = var2, y = avg2, fill = var2)) +
geom_bar(stat = "identity",
width = 1) +
facet_grid(wave ~ forcats::fct_relevel(outcome_type, "CT", "CI", "CE", "FZ", "MZ", "PSS", "CSS"),
scales = "free_y",
space = "free_y") +
theme_minimal() +
theme(legend.position = "none")
dtest <- structure(list(outcome_type = c("CT", "CT", "CT", "CI", "CI",
"CI", "CE", "CE", "CE", "FZ", "FZ", "MZ", "MZ", "PSS", "PSS",
"CSS", "CSS", "CT", "CT", "CT", "CI", "CI", "CI", "CE", "CE",
"CE", "FZ", "FZ", "MZ", "MZ", "PSS", "PSS", "CSS", "CSS"), wave = c("Wave 1",
"Wave 2", "Wave 3", "Wave 1", "Wave 2", "Wave 3", "Wave 1", "Wave 2",
"Wave 3", "Wave 2", "Wave 3", "Wave 2", "Wave 3", "Wave 1", "Wave 3",
"Wave 1", "Wave 3", "Wave 1", "Wave 2", "Wave 3", "Wave 1", "Wave 2",
"Wave 3", "Wave 1", "Wave 2", "Wave 3", "Wave 2", "Wave 3", "Wave 2",
"Wave 3", "Wave 1", "Wave 3", "Wave 1", "Wave 3"), var2 = c("Skipped",
"Skipped", "Skipped", "Skipped", "Skipped", "Skipped", "Skipped",
"Skipped", "Skipped", "Skipped", "Skipped", "Skipped", "Skipped",
"Skipped", "Skipped", "Skipped", "Skipped", "Attended", "Attended",
"Attended", "Attended", "Attended", "Attended", "Attended", "Attended",
"Attended", "Attended", "Attended", "Attended", "Attended", "Attended",
"Attended", "Attended", "Attended"), avg2 = c(30.21, 20.88, 25.43,
7.68, 8.26, 7.89, 11.15, 8, 5.99, 1.64, 0.43, 0.6, 0.77, 0.01,
-0.09, -0.2, -0.01, 24.01, 19.98, 29.04, 9.82, 12.41, 12.99,
14.35, 11.01, 10, 2.36, 2.3, 1.51, 0.91, -0.23, -0.35, -0.17,
-0.14), outcome_type2 = c("C", "C", "C", "C", "C", "C", "C",
"C", "C", "Z", "Z", "Z", "Z", "SS", "SS", "SS", "SS", "C", "C",
"C", "C", "C", "C", "C", "C", "C", "Z", "Z", "Z", "Z", "SS",
"SS", "SS", "SS")), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -34L), spec = structure(list(
cols = list(outcome_type = structure(list(), class = c("collector_character",
"collector")), wave = structure(list(), class = c("collector_character",
"collector")), var2 = structure(list(), class = c("collector_character",
"collector")), avg2 = structure(list(), class = c("collector_double",
"collector")), outcome_type2 = structure(list(), class = c("collector_character",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1L), class = "col_spec"))
One option would be to create separate plots for each group of panels and glue them together using patchwork. Doing so you get "free" scale for each group of panels automatically and also have one (and only one) axis for each panel group.
To this end first add a group column to your data which could be used to split your dataset by facet panel group. Additionally, for convenience I use a plotting function which also removes the y axis strip texts for the first two groups of panels and as an important step completes each dataset so that all combinations of wave, outcome_type and var2 are present in each sub-dataset.
library(ggplot2)
library(patchwork)
library(magrittr)
dtest$group <- dplyr::case_when(
grepl("SS$", dtest$outcome_type) ~ "SS",
grepl("Z$", dtest$outcome_type) ~ "Z",
TRUE ~ "C"
)
dtest$group <- factor(dtest$group, c("C", "Z", "SS"))
plot_fun <- function(.data) {
remove_facet <- if (unique(.data$group) %in% c("C", "Z")) {
theme(strip.text.y = element_blank())
}
.data$outcome_type <- forcats::fct_relevel(
.data$outcome_type,
"CT", "CI", "CE", "FZ", "MZ", "PSS", "CSS"
)
.data |>
tidyr::complete(outcome_type, wave = unique(dtest$wave), var2) %>%
ggplot(aes(x = var2, y = avg2, fill = var2)) +
geom_bar(
stat = "identity",
width = 1
) +
facet_grid(wave ~ outcome_type) +
theme_minimal() +
remove_facet
}
dtest_split <- split(dtest, dtest$group)
lapply(dtest_split, plot_fun) %>%
wrap_plots() +
plot_layout(widths = c(3, 2, 2), guides = "collect") &
labs(x = NULL, y = NULL, fill = NULL) &
theme(axis.text.x = element_blank())
#> Warning: 4 unknown levels in `f`: FZ, MZ, PSS, and CSS
#> Warning: 5 unknown levels in `f`: CT, CI, CE, PSS, and CSS
#> Warning: 5 unknown levels in `f`: CT, CI, CE, FZ, and MZ
#> Warning: Removed 4 rows containing missing values (`position_stack()`).
#> Removed 4 rows containing missing values (`position_stack()`).
Here is a solution where we first identify those avg2 < 5, then make a list of two data frames and plot for each data frame the corresponding plot:
library(tidyverse)
require(gridExtra)
my_list <- dtest %>%
pivot_longer(c(contains("type"))) %>%
mutate(value = fct_relevel(value, "CT", "CI", "CE", "FZ", "MZ", "PSS", "CSS")) %>%
arrange(value) %>%
mutate(x = ifelse(avg2 <5, 1, 0)) %>%
group_split(x)
plot1 <- ggplot(my_list[[1]], aes(x = var2, y = avg2, fill = var2))+
geom_col()+
facet_grid(wave ~ value) +
theme_minimal() +
theme(legend.position = "none",
strip.text.y = element_blank()
)
plot2 <- ggplot(my_list[[2]], aes(x = var2, y = avg2, fill = var2))+
geom_col()+
facet_grid(wave ~ value)+
theme_minimal() +
theme(legend.position = "none")+
labs(y="")
grid.arrange(plot1, plot2, ncol=2)

Is there a way to change legend to show increasing and decreasing colors for waterfall plot using Plotly (r)?

I've plotted a waterfall chart/plot using plotly. I'm trying to change the legend so that it displays the increasing/decreasing colors (red/green) that I've set. Does anyone know how I would go about doing this? I'm try display only one legend for the entire figure rather than one legend for each subplot. Currently, what displays is the trace with a red and green box (as I've indicated in the picture).
Here is the data:
structure(list(Date = structure(c(1569888000, 1572566400, 1575158400,
1577836800, 1580515200, 1583020800, 1585699200, 1588291200, 1590969600,
1569888000, 1572566400, 1575158400, 1577836800, 1580515200, 1583020800,
1585699200, 1588291200, 1590969600, 1569888000, 1572566400, 1575158400,
1577836800, 1580515200, 1583020800, 1585699200, 1588291200, 1590969600
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Percent_change = c(-45,
-50, -25, -30, -40, -35, -1, -5, -25, 30, 45, 50, -30, -40, -35,
-1, -5, -25, 50, -45, -30, -15, -20, -35, -1, -5, -25), Toys = c("Toy 1",
"Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 1",
"Toy 1", "Toy 2", "Toy 2", "Toy 2", "Toy 2", "Toy 2", "Toy 2",
"Toy 2", "Toy 2", "Toy 2", "Toy 3", "Toy 3", "Toy 3", "Toy 3",
"Toy 3", "Toy 3", "Toy 3", "Toy 3", "Toy 3")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -27L))
Here is the code:
percent <- function(x, digits = 2, format = "f", ...) {
paste0(formatC(x, format = format, digits = digits, ...), "%")
}
my_plot <- . %>%
plot_ly(x = ~Date, y = ~Percent_change, type = "waterfall",
hoverinfo = "text",
hovertext = ~paste("Date :", Date,
"<br> % Change:", percent(Percent_change)),
increasing = list(marker = list(color = "red")),
decreasing = list(marker = list(color = "green")),
totals = list(marker = list(color = "blue")),
textposition = "outside", legendgroup = "trace 1") %>%
add_annotations(
text = ~unique(Toys),
x = 0.5,
y = 1,
yref = "paper",
xref = "paper",
xanchor = "middle",
yanchor = "top",
showarrow = FALSE,
font = list(size = 15),
yshift = 10
) %>%
layout(yaxis = list(title = "% Change",
ticksuffix = "%"),
xaxis = list(title = c("Date")),
showlegend =T)
example_data %>%
dplyr::filter(!is.na(Date)) %>%
group_by(Toys) %>%
distinct() %>%
do(p = my_plot(.)) %>%
subplot(nrows = 3, shareX = FALSE, titleY= TRUE, titleX= FALSE)
I would like the legend to specifically look like this with the title "Trend" above:
We can create two initial traces representing the two legend items.
After that we need to assign all increasing and decreasing traces into the legendgroups introduced with the initial traces and hide their legend items:
library(plotly)
library(dplyr)
library(data.table)
example_data <- structure(list( Date = structure(c(1569888000, 1572566400,
1575158400, 1577836800, 1580515200, 1583020800, 1585699200, 1588291200,
1590969600, 1569888000, 1572566400, 1575158400, 1577836800, 1580515200,
1583020800, 1585699200, 1588291200, 1590969600, 1569888000, 1572566400,
1575158400, 1577836800, 1580515200, 1583020800, 1585699200, 1588291200,
1590969600), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Percent_change =
c(-45, -50, -25, -30, -40, -35, -1, -5, -25, 30, 45, 50, -30, -40, -35, -1,
-5, -25, 50, -45, -30, -15, -20, -35, -1, -5, -25), Toys = c("Toy 1", "Toy 1",
"Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 1", "Toy 2", "Toy 2",
"Toy 2", "Toy 2", "Toy 2", "Toy 2", "Toy 2", "Toy 2", "Toy 2", "Toy 3",
"Toy 3", "Toy 3", "Toy 3", "Toy 3", "Toy 3", "Toy 3", "Toy 3", "Toy 3")),
class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -27L))
percent <- function(x, digits = 2, format = "f", ...) {
paste0(formatC(x, format = format, digits = digits, ...), "%")
}
my_plot <- . %>%
plot_ly(
x = ~ Date[1],
y = 0,
type = "bar",
name = "increasing",
color = I("darkgreen"),
legendgroup = "increasing",
showlegend = ~ all(showlegend)
) %>%
add_trace(
x = ~ Date[1],
y = 0,
type = "bar",
name = "decreasing",
color = I("red"),
legendgroup = "decreasing",
showlegend = ~ all(showlegend)
) %>%
add_trace(
x = ~ Date,
y = ~ Percent_change,
type = "waterfall",
# split = ~ legendgroup,
hoverinfo = "text",
hovertext = ~ paste("Date :", Date, "<br> % Change:", percent(Percent_change)),
increasing = list(marker = list(color = "red")),
decreasing = list(marker = list(color = "green")),
totals = list(marker = list(color = "blue")),
textposition = "outside",
legendgroup = ~ legendgroup,
showlegend = FALSE
) %>%
add_annotations(
text = ~ unique(Toys),
x = 0.5,
y = 1,
yref = "paper",
xref = "paper",
xanchor = "middle",
yanchor = "top",
showarrow = FALSE,
font = list(size = 15),
yshift = 10
) %>%
layout(yaxis = list(title = "% Change", ticksuffix = "%"),
xaxis = list(title = c("Date")),
legend = list(
itemclick = FALSE,
itemdoubleclick = FALSE,
groupclick = FALSE
))
example_data %>%
dplyr::filter(!is.na(Date)) %>%
mutate(legendgroup = case_when(
Percent_change >= 0 ~ "increasing",
Percent_change < 0 ~ "decreasing",
)) %>%
mutate(showlegend = data.table::rleid(Toys, legendgroup) %in% c(1, 2)) %>%
group_by(Toys) %>%
distinct() %>%
do(p = my_plot(.)) %>%
subplot(
nrows = 3,
shareX = FALSE,
titleY = TRUE,
titleX = FALSE
)
PS: if you prefer to display your waterfall using separate traces for the increasing and decreasing parts use split = ~ legendgroup in the add_trace call. Furthermore you'll need to set itemclick etc. back to TRUE in the layout call for an interactive legend.
You can edit the legend name in R and use javascript to edit the legend colors
Edit: I'll leave this here as it is a different approach which is sometimes useful, but I think the answer by #ismirsehregal - which doesn't involve hacking the object created by plotly.js - is better.
Steps:
Re-define your my_plot() function so that it names the first trace "decreasing" and the second one "increasing".
Append some javascript to manually change the legend colors.
Call the function, hiding the third legend, and appending the javascript
1. Redefine the function
This is the same as your function except it maps the first two groups to "increasing" or "decreasing".
my_plot <- function(x,
group_name,
groups_to_show_legend = c(
"Toy 1" = "decreasing", "Toy 2" = "increasing"
)) {
x %>%
plot_ly(
x = ~Date, y = ~Percent_change, type = "waterfall",
hoverinfo = "text",
hovertext = ~ paste(
"Date :", Date,
"<br> % Change:", percent(Percent_change)
),
increasing = list(marker = list(color = "red")),
decreasing = list(marker = list(color = "green")),
totals = list(marker = list(color = "blue")),
textposition = "outside",
legendgroup = "trace 1",
name = groups_to_show_legend[group_name]
) %>%
add_annotations(
text = ~ unique(Toys),
x = 0.5,
y = 1,
yref = "paper",
xref = "paper",
xanchor = "middle",
yanchor = "top",
showarrow = FALSE,
font = list(size = 15),
yshift = 10
) %>%
layout(
yaxis = list(
title = "% Change",
ticksuffix = "%"
),
xaxis = list(title = c("Date")),
showlegend = TRUE
)
}
2. Append some javascript
We can define some a javascript string in R which we feed to the htmlwidget created by plotly. This makes the "decreasing" symbol red and the "increasing" symbol green.
js_text <- htmltools::HTML('
let legend = document.querySelector(\'.scrollbox\');\n
let symbols = legend.getElementsByClassName("legendsymbols");\n
const re = new RegExp("fill: rgb.*?;", "ig");\n
symbols[0].innerHTML = symbols[0].innerHTML.replaceAll(re, "fill: rgb(255, 0, 0);");\n
symbols[1].innerHTML = symbols[1].innerHTML.replaceAll(re, "fill: rgb(0, 128, 0);");\n
')
3. Call the function, hiding the third legend, and appending the javascript
I've replaced do(), which is deprecated, with split() followed by purrr::imap(). This also allows us to supply the group names to the function:
example_data |>
dplyr::filter(!is.na(Date)) |>
group_by(Toys) |>
distinct() |>
split(~Toys) |>
purrr::imap(my_plot) |>
subplot(
nrows = 3,
shareX = FALSE,
titleY = TRUE,
titleX = FALSE
) |>
style(showlegend = FALSE, traces = 3) |>
htmlwidgets::prependContent(
htmlwidgets::onStaticRenderComplete(js_text)
)
We use htmlwidgets::prependContent() to attach this code to the plotly object, and htmlwidgets::onStaticRenderComplete() to ensure that it runs once the object is loaded.
You could use style to remove multiple traces. This creates one legend for your graph like this:
library(plotly)
library(dplyr)
my_plot <- . %>%
plot_ly(x = ~Date, y = ~Percent_change, type = "waterfall",
hoverinfo = "text",
hovertext = ~paste("Date :", Date,
"<br> % Change:", percent(Percent_change)),
increasing = list(marker = list(color = "red")),
decreasing = list(marker = list(color = "green")),
totals = list(marker = list(color = "blue")),
textposition = "outside", legendgroup = "trace 1") %>%
add_annotations(
text = ~unique(Toys),
x = 0.5,
y = 1,
yref = "paper",
xref = "paper",
xanchor = "middle",
yanchor = "top",
showarrow = FALSE,
font = list(size = 15),
yshift = 10
) %>%
layout(yaxis = list(title = "% Change",
ticksuffix = "%"),
xaxis = list(title = c("Date")),
showlegend = TRUE)
example_data %>%
dplyr::filter(!is.na(Date)) %>%
group_by(Toys) %>%
distinct() %>%
do(p = my_plot(.)) %>%
subplot(nrows = 3, shareX = FALSE, titleY= TRUE, titleX= FALSE) %>%
style(showlegend = FALSE, traces = c(1,2))
Created on 2023-02-08 with reprex v2.0.2

How to add ribbon/shading to density plot

This is the dput output.
structure(list(data = structure(list(stations = c("s1", "s2",
"s3", "s4", "s5", "s1", "s2", "s3", "s4", "s5", "s1", "s2", "s3",
"s4", "s5", "s1", "s2", "s3", "s4", "s5"), Mean = c(792.0666667,
830.0666667, 542.4666667, 311.3333333, NA, 535.3222222, 576.9855556,
510.0756667, 433.9747778, 347.35, 726.9027778, 798.3153333,
706.2138889, 593.0828889, 474.9132222, 991.5945841, 1044.328044,
693.3808187, 403.8107808, NA), stdev = c(189.6764965, 123.9226103,
115.742876, 70.03437251, NA, 300.4539788, 306.3421887, 274.6515927,
237.7002122, 191.230147, 197.9449891, 248.458886, 203.0634826,
156.500875, 124.8746002, 265.4692578, 190.0975192, 185.9667516,
119.4178709, NA), Lower = c(602.3901701, 706.1440564, 426.7237907,
241.2989608, NA, 234.8682435, 270.6433669, 235.424074, 196.2745655,
156.119853, 528.9577886, 549.8564473, 503.1504063, 436.5820139,
350.038622, 726.1253263, 854.2305244, 507.4140671, 284.3929099, NA),
Upper = c(981.7431632, 953.9892769, 658.2095426, 381.3677058, NA,
835.776201, 883.3277442, 784.7272594, 671.67499, 538.580147,
924.8477669, 1046.774219, 909.2773715, 749.5837639, 599.7878224,
1257.063842, 1234.425563, 879.3475703, 523.2286518, NA), Group =
c("Observation", "Observation", "Observation", "Observation",
"Observation", "Historical", "Historical", "Historical", "Historical",
"Historical", "Future", "Future", "Future", "Future", "Future",
"Downscaled", "Downscaled", "Downscaled", "Downscaled", "Downscaled")),
class = "data.frame", row.names = c(NA, -20L)), layers =
list(<environment>, <environment>), scales = <environment>,
mapping = structure(list(x = ~Mean, Group = ~Group), class =
"uneval"), theme = list(), coordinates = <environment>, facet =
<environment>, plot_env = <environment>, labels = list(title =
"Probability density functions (PDF) for in comparison with
observations", y = "Probability density function", x = "March maximum
temperature", Group = "Group", colour = "factor(Group)", linetype =
"factor(Group)", fill = structure("fill", fallback = TRUE), weight =
structure("weight", fallback = TRUE))), class = c("gg",
"ggplot"))
I have produced density plot using ggplot2. The density plot is the mean. I want to shade each density line by lower and upper bounds just like confidence intervals. Please can anyone help how to achieve this?
The code I used to generate density in ggplot
ggplot(pdf1, aes(x=Mean, Group=Group)) +
geom_density(aes(colour=factor(Group), linetype=factor(Group)),
show.legend = FALSE) +
stat_density(aes(x=Mean, colour=factor(Group),
linetype=factor(Group)),
geom="line",position="identity", linewidth=1) +
xlab("March maximum temperature") +
ylab("Probability density function") +
ggtitle("Probability density functions (PDF) for in comparison with
observations") +
scale_linetype_manual(values=c('solid', 'solid','solid','dotted'),
labels=c("Observation", "Historical", "Future",
"Downscaled")) +
scale_colour_manual(values = c("black", "green", "blue", "red"),
labels=c("Observation", "Historical", "Future",
"Downscaled"))
This is the output from the above code
I searched in the net and could not find the solution.
Thanks a lot for your help!
This is a kind of output I am looking for (https://rpubs.com/Grady/875225). But as you can see, it has both x and y variables but I only have one variable (Mean in my case) in the x-axis while it is probability density in the y-axis in the above ggplot. So, I want to use the lower and upper values to envelope each line with shades with each respective color of my density plot

How to remove outliers from nonlinear regression curve? with 3-sigma limits?

I tried to remove outliers from nonlinear regression curve, and get the updated formula and error criteria. Someone suggested me to use 3-sigma limits, a statistical calculation where the data are within three standard deviations from a mean. But I don't know how to realize it in my case.
Here is the original data.
ISIDOR <- structure(list(Pos_heliaphen = c("W30", "X41", "Y27", "Z24",
"Y27", "W30", "W30", "X41", "Y27", "W30", "X41", "Z40", "Z99"
), traitement = c("WW", "WW", "WW", "WW", "WW", "WW", "WW", "WW",
"WW", "WW", "WW", "WW", "WW"), Variete = c("Isidor", "Isidor",
"Isidor", "Isidor", "Isidor", "Isidor", "Isidor", "Isidor", "Isidor",
"Isidor", "Isidor", "Isidor", "Cali"), FTSW_apres_arros = c(0.462837958498518,
0.400045032939416, 0.352560790392534, 0.377856799586057, 0.170933345859364,
0.315689846065931, 0.116825600914318, 0.0332444780173884, 0.00966070114456602,
0.0871102539376406, 0.0107280083093036, 0.195548432729584, 1),
NLE = c(0.903498791068124, 0.954670066942938, 0.970762905436272,
0.873838605282389, 0.647875257025359, 0.53056603773585, 0.0384548155916796,
0.0470924009989314, 0.00403163281128882, 0.193696514297641,
0.0718450645564359, 0.295346695941639, 1)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -13L))
Here is my original code.
pred_df <- data.frame(FTSW_apres_arros = seq(min(ISIDOR$FTSW_apres_arros),
max(ISIDOR$FTSW_apres_arros),
length.out = 100))
pred_df$NLE <- predict(mod, newdata = pred_df)
mod = nls(NLE ~ 2/(1+exp(a*FTSW_apres_arros))-1,start = list(a=1),data = ISIDOR)
ISIDOR$pred = predict(mod,ISIDOR)
a = coef(mod)
RMSE = rmse(ISIDOR$NLE, ISIDOR$pred)
MSE = mse(ISIDOR$NLE, ISIDOR$pred)
Rsquared = summary(lm(ISIDOR$NLE~ ISIDOR$pred))$r.squared
ggplot(ISIDOR, aes(FTSW_apres_arros, NLE)) +
geom_point(aes(color = Variete), pch = 19, cex = 3) +
geom_line(data = pred_df) +
scale_color_manual(values = c("red3","blue3"))+
scale_y_continuous(limits = c(0, 1.0)) +
scale_x_continuous(limits = c(0, 1)) +
labs(title = "Isidor",
y = "Expansion folliaire totale relative",
x = "FTSW",
subtitle = paste0("y = 2/(1 + exp(", round(a, 3), "* x)) -1)","\n",
"R^2 = ", round(Rsquared, 3)," RMSE = ",
round(RMSE, 3), " MSE = ", round(MSE, 3)))+
theme(plot.title = element_text(hjust = 0, size = 14, face = "bold",
colour = "black"),
plot.subtitle = element_text(hjust = 0,size=10, face = "italic",
colour = "black"),
legend.position = "none")
Here is the picture I got. I also want to get the updated formula and error criteria (circled in red).
If 3-sigma limits doesn't work for my case, could anyone recommend me other ways to deal with outliers?

How to wrap long titles in lattice graphics in R?

I need to add a long title to a graphic created with the likert function from the HH package, that uses lattice, but it (lattice) doesn't have this facility. Is there a way to do this?
My code:
library(HH)
ppi <- 150
jpeg("ssb_%02d.jpg", width=7*ppi, height=4*ppi, res=ppi)
for(i in 1:2){
plot_obj <- likert(Grup ~ . | Grup, data = ssb, as.percent = TRUE, positive.order = TRUE,
main=list(label = items[i,], cex=1.2), xlab=list(label="Percent", cex=1.1),
ylab="", ylab.right = list("Subjects per group", cex=1.1),
scales = list(y = list(relation = "free", labels=""), cex=1.1),
layout = c(1, 2), auto.key=list(space="bottom", columns=3, title="", cex=1.1))
print(plot_obj)
}
dev.off()
My data:
ssb <- structure(list(`Strongly Disagree` = c(2L, 1L), `Moderate Disagree` = 1:2,
`Slightly Disagree` = c(3L, 1L), `Slightly Agree` = c(1L,
5L), `Moderate Agree` = 4:5, `Strongly Agree` = c(9L, 6L),
Grup = c("Experimental grup", "Control grup")), .Names = c("Strongly Disagree",
"Moderate Disagree", "Slightly Disagree", "Slightly Agree", "Moderate Agree",
"Strongly Agree", "Grup"), row.names = c("1", "2"), class = "data.frame")
Title items:
items <- structure(list(V1 = structure(1:2, .Label = c("1. În cele mai multe privinţe, viaţa mea corespunde idealului meu.",
"2. Până în prezent am primit cele mai importante lucruri pe care le doresc în viață."
), class = "factor")), .Names = "V1", class = "data.frame", row.names = c(NA,
-2L))
UPDATE
Graphic titles are not added directly, but dynamically, from a data frame, and the data frame are loaded from a .csv file. If, as was suggested in comments, I add a \n to the long title in the .csv file this doesn't work.
I solved my problem, thanks to #josh-obrien. Now, when the graphic title is longer than 70 characters it is wrapped to 65 characters wide version.
library(HH)
ppi <- 150
jpeg("ssb_%02d.jpg", width=7*ppi, height=4*ppi, res=ppi)
for(i in 1:2){
if(stri_length(items[i,])>70){
graphic.title <- paste(strwrap(items[i,], width = 65), collapse="\n")
} else {
graphic.title <- items[i,]
}
plot_obj <- likert(Grup ~ . | Grup, data = ssb, as.percent = TRUE, positive.order = TRUE,
main=list(label = graphic.title, cex=1.2), xlab=list(label="Percent", cex=1.1),
ylab="", ylab.right = list("Subjects per group", cex=1.1),
scales = list(y = list(relation = "free", labels=""), cex=1.1),
layout = c(1, 2), auto.key=list(space="bottom", columns=3, title="", cex=1.1))
print(plot_obj)
}
dev.off()

Resources