Related
I currently have trouble plotting a 3D pie chart whereas it had worked well with a very similar dataset.
Here is my dataset :
structure(list(type_de_sejour = structure(1:4, levels = c("Ambulatoires",
"Externes", "Fictifs", "Hospitalisé"), class = "factor"), nb_sejours_2021 = c(20794,
365, 0, 7866)), row.names = c(NA, -4L), class = "data.frame")
And here is my code :
lab <- paste0(round(pie1_PGS$nb_sejours_2021/sum(pie1_PGS$nb_sejours_2021) * 100, 2),
"%")
pie3D(pie1_PGS$nb_sejours_2021, radius = 0.75,
height = 0.1,
theta = 0.7,
border = "white",
col = rainbow(length(lab)),
shade = 0.5,
labels = lab,
labelcol = "red",
labelcex = 0.75,
explode = 0.2,
main = "Répartition des séjours 2021 par type")
I get the following message of error :
"Error in seq.default(start, end, by = angleinc) :
(to - from) / by incorrect"
Also, I would like to plot a legend to indicate what the colours mean (they take the values of variable type_de_sejour). I have seen several posts here, but I can't seem to manage to do it on this dataset, so I would welcome any help regarding this issue too.
Here is the code I added :
legend(0.5, 1.5, c("Ambulatoires","Externes", "Hospitalisé",
"Séances"), cex = 0.3,
fill = rainbow(length(lab)))
I think the problem is that the legend is too big as regards the plot...
Add legend
You can use the function legend like this:
pie1_PGS <- structure(list(type_de_sejour = structure(1:4, levels = c("Ambulatoires",
"Externes", "Fictifs", "Hospitalisé"), class = "factor"), nb_sejours_2021 = c(20794,
365, 0, 7866)), row.names = c(NA, -4L), class = "data.frame")
pie1_PGS <- pie1_PGS[!(pie1_PGS$nb_sejours_2021 == 0),]
lab <- paste0(round(pie1_PGS$nb_sejours_2021/sum(pie1_PGS$nb_sejours_2021) * 100, 2),
"%")
library(plotrix)
pie3D(pie1_PGS$nb_sejours_2021,
radius = 0.75,
height = 0.1,
theta = 0.7,
border = "white",
col = rainbow(length(lab)),
shade = 0.5,
labels = lab,
labelcol = "red",
labelcex = 0.75,
explode = 0.2,
main = "Répartition des séjours 2021 par type")
legend(0.1, 0.9, pie1_PGS$type_de_sejour, cex = 0.7, fill = rainbow(length(lab)))
Created on 2022-08-11 by the reprex package (v2.0.1)
You should remove the rows with 0 value because you can't show them in a pie chart. You can use the following code:
pie1_PGS <- structure(list(type_de_sejour = structure(1:4, levels = c("Ambulatoires",
"Externes", "Fictifs", "Hospitalisé"), class = "factor"), nb_sejours_2021 = c(20794,
365, 0, 7866)), row.names = c(NA, -4L), class = "data.frame")
pie1_PGS <- pie1_PGS[!(pie1_PGS$nb_sejours_2021 == 0),]
lab <- paste0(round(pie1_PGS$nb_sejours_2021/sum(pie1_PGS$nb_sejours_2021) * 100, 2),
"%")
library(plotrix)
pie3D(pie1_PGS$nb_sejours_2021,
radius = 0.75,
height = 0.1,
theta = 0.7,
border = "white",
col = rainbow(length(lab)),
shade = 0.5,
labels = lab,
labelcol = "red",
labelcex = 0.75,
explode = 0.2,
main = "Répartition des séjours 2021 par type")
Created on 2022-08-10 by the reprex package (v2.0.1)
I have got this code that is in R Markdown and uses plotly. I want to add a limit on Y axis. Here it uses the maximum of "est" variables but I want to put a cut off of 10.
I understand that this would affect the confidence interval (upper and lower) as well.
I have provided the data using dput() here. Hope this is the right way as its first time using this function.
dput(plot_data)
structure(list(quarter = structure(c(2014.25, 2015.5, 2015.75,
2016, 2016.25, 2016.5, 2016.75, 2017, 2017.25, 2017.5, 2017.75,
2018, 2018.25, 2018.5, 2018.75, 2019, 2019.25, 2019.5, 2019.75,
2020, 2020.25, 2020.5, 2020.75, 2021, 2021.25, 2021.75), class = "yearqtr"),
cases = c(1L, 1L, 38L, 4L, 2L, 8L, 9L, 13L, 6L, 20L, 32L,
42L, 26L, 18L, 25L, 11L, 5L, 4L, 4L, 3L, 1L, 2L, 2L, 2L,
3L, 1L), est = c(0, 0, 0, 21, 0.153846153846154, 0.238095238095238,
2.83333333333333, 2.2, 1.11764705882353, 1.18181818181818,
2.73684210526316, 2.84615384615385, 1.30769230769231, 0.594594594594595,
0.632352941176471, 0.818181818181818, 0.372093023255814,
0.25, 0.5, 0.777777777777778, 0.5, 0.428571428571429, 1,
1.33333333333333, 1.25, 1), lower = c(0, 0, 0, 9.36875, 0.0605698529411765,
0.0900568181818182, 1.24583333333333, 1.0825, 0.537, 0.704503105590062,
1.88461538461538, 1.96911764705882, 0.914764492753623, 0.402261904761905,
0.390400682011935, 0.539913043478261, 0.224595551061679,
0.103584229390681, 0.213787185354691, 0.25, 0.105277777777778,
0, 0.1825, 0.0950000000000005, 0.2, 0.154166666666667), upper = c(0,
0, 0, 9, 0.287045454545454, 0.448195187165775, 9, 4.98499999999999,
2.49523809523809, 2.1875, 4.5, 4.60504201680672, 1.88531641397495,
0.867572463768115, 0.869867374005305, 1.35281440162272, 0.629361179361179,
0.457125307125307, 1.09090909090909, 2.17285714285714, 3,
2.68333333333333, 9, 9, 7.52499999999999, 6)), row.names = c(NA,
-26L), class = c("tbl_df", "tbl", "data.frame"))
plot_data <- tibble(
quarter = rp_list$infection_quarter,
cases = rp_list$cases,
est = edr_frame$est,
lower = edr_frame$lower,
upper = edr_frame$upper
) %>%
mutate (upper = case_when(upper >= 10 ~9,
upper >= 9 ~ 8,
TRUE ~ upper))
plot_edr <- plot_data %>%
# Dashed line for upper CI
plotly::plot_ly(
name = "95% CI (upper)",
type = 'scatter',
mode = 'lines',
x = ~quarter,
y = ~upper,
line = list(
dash = "dot",
color = c("#A8B9CB")
)
) %>%
add_trace(
name = "95% CI (lower)",
type = 'scatter',
mode = 'lines',
x = ~quarter,
y = ~lower,
line = list(
dash = "dot",
color = c("#A8B9CB")
)
) %>%
add_trace(
name = "EDR",
type = 'scatter',
mode = 'lines',
x = ~quarter,
y = ~est,
line = list(
dash = "line",
color = c("#2F3D70")
)
) %>%
layout(
title = 'Ratio',
xaxis = list(title = "Quarter"),
yaxis = list(title = "Ratio with 95% CI"),
shapes = list(
list(type = "rect",
fillcolor = "green", line = list(color = "green"), opacity = 0.1,
x0 = min(plot_data$quarter), x1 = max(plot_data$quarter), xref = "x",
y0 = 0, y1 = 1, yref = "y"),
list(type = "rect",
fillcolor = "red", line = list(color = "red"), opacity = 0.1,
x0 = min(plot_data$quarter), x1 = max(plot_data$quarter), xref = "x",
y0 = 1, y1 = max(plot_data$upper), yref = "y1")))
Many Thanks
You should add range = c(0,10) to your yaxis in your layout the plot. You can use the following code:
library(plotly)
library(tidyverse)
plot_edr <- plot_data %>%
# Dashed line for upper CI
plotly::plot_ly(
name = "95% CI (upper)",
type = 'scatter',
mode = 'lines',
x = ~quarter,
y = ~upper,
line = list(
dash = "dot",
color = c("#A8B9CB")
)
) %>%
add_trace(
name = "95% CI (lower)",
type = 'scatter',
mode = 'lines',
x = ~quarter,
y = ~lower,
line = list(
dash = "dot",
color = c("#A8B9CB")
)
) %>%
add_trace(
name = "EDR",
type = 'scatter',
mode = 'lines',
x = ~quarter,
y = ~est,
line = list(
dash = "line",
color = c("#2F3D70")
)
) %>%
layout(
title = 'Ratio',
xaxis = list(title = "Quarter"),
yaxis = list(title = "Ratio with 95% CI", range = c(0,10)),
shapes = list(
list(type = "rect",
fillcolor = "green", line = list(color = "green"), opacity = 0.1,
x0 = min(plot_data$quarter), x1 = max(plot_data$quarter), xref = "x",
y0 = 0, y1 = 1, yref = "y"),
list(type = "rect",
fillcolor = "red", line = list(color = "red"), opacity = 0.1,
x0 = min(plot_data$quarter), x1 = max(plot_data$quarter), xref = "x",
y0 = 1, y1 = max(plot_data$upper), yref = "y1")))
Output:
I have an issue with plotting continuous distributions without sharp edges in ggplot2. I need to show two of them on one plot. Also, it does not have to be ggplot2 to achieve this result.
I am aware, that the number of data points directly influences the smoothness of the line, but it was not the case here. Below you can see some sample data (from dput)
sample.data<-list(beta.data = structure(list(cluster = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), beta.density = c(0, 3.42273368363934e-43, 8.42987148403021e-29,
2.04764468657484e-20, 1.69485562831516e-14, 6.07999638837842e-10, 2.88180370232676e-06, 0.00314064636750876, 0.954118897015866, 0, 0, 3.80101893822358e-36, 6.43342582657081e-22, 6.82956252277493e-14, 1.75291058931833e-08, 0.000131874335695378, 0.0750918340641428, 3.72532418759802, 5.05242078519544, 0), pr = c(0, 0.111111111111111, 0.222222222222222, 0.333333333333333, 0.444444444444444, 0.555555555555556, 0.666666666666667, 0.777777777777778, 0.888888888888889, 1, 0, 0.111111111111111, 0.222222222222222, 0.333333333333333, 0.444444444444444, 0.555555555555556, 0.666666666666667, 0.777777777777778, 0.888888888888889, 1)), row.names = c(NA, -20L), class = "data.frame"), beta.params = structure(list(cluster = 1:2, a = c(49, 50), b = c(2, 10), ni.beta = c(0.961,0.833), sd.beta = c(0.00072, 0.00228)), row.names = c(NA,-2L), class = "data.frame"))
Before I was using geom_col, but it discretizes values. I went with geom_area:
ggplot(sample.data$beta.data, aes(x = pr, y = beta.density)) +
geom_area(stat = "function",
fun = dbeta,
args = list(shape1 = sample.data$beta.params[1,"a"], shape2 = sample.data$beta.params[1,"b"]),
fill = "#F1C40F",
colour = "black",
alpha = 0.7) +
geom_area(stat = "function",
fun=dbeta,
args = list(shape1 = sample.data$beta.params[2,"a"], shape2 = sample.data$beta.params[2,"b"]),
fill = "#3498DB",
colour = "black",
alpha = 0.7)
I presented you the data with 10 points, but 1000 points look almost the same. It is not the case here, where even 100 points looks ok:
p = seq(0,1, length=100)
plot(p, dbeta(p, 50, 10), ylab="Density", type ="l", col=4, , lwd = 2)
Here I am attaching code to simulate the data. Oh, and these troublesome beta parameters were a = 49 and b = 2.
len <- 100
p <- seq(0,1, length.out = len)
df <- data.frame(rbind(cbind("cl" = rep(1, times = length(p)), "beta" = dbeta(p, 50, 10),"p"= p),
cbind("cl" = rep(1, times = length(p)), "beta" = dbeta(p, 40, 2),"p"= p)))
Do you have any ideas?
EDIT: The pdfs stands here for probability density functions. That is why I have not put "pdf" as a tag. My apologies for the confusion!
Anyway, when I tried to print graphic to PDF file, the result was poor as well (sharp edges). But it the end, it shouldn't matter. I want to see smooth lines whatever I do (reasonably).
EDIT2 It is possible to achieve because:
library(mosaic)
theme_set(theme_bw())
xpbeta(c(0.7, 0.90), shape1 = 49, shape2 = 2)
It produces nice, smoothed beta dist with parameters (49, 2). But then again, I need to show two dists in one chart.
I have found the answer. It still needs some editing (like transparency/alpha which I couldn't figure out), but in general, this is what I meant. Code:
library(mosaic)
plotDist('beta', params=list(49,2), kind='density', type = "h", col = "#3498DB", xlim = c(0,1))
plotDist('beta', params=list(50, 10), kind='density', , type = "h", col = "#F1C40F", add = TRUE)
plotDist('beta', params=list(49,2), kind='density', add = TRUE, col = "black")
plotDist('beta', params=list(50, 10), kind='density', add = TRUE, col = "black")
Result:
We can add as many distributions as we want, using "add" parameter.
Parameter type = "h", is used to draw filled distribution. Without it, the only line is visible. In my answer, I draw the two lines and two filled dists. I would be really happy if someone could show a better answer, though.
EDIT:
I think I found my perfect answer!
Here is the code:
library(ggformula)
theme_set(theme_bw())
gf_dist("beta", shape1 = 49, shape2 = 2, geom = "area", alpha = 0.5, fill = "#F1C40F") %>%
gf_dist("beta", shape1 = 49, shape2 = 2) %>%
gf_dist("beta", shape1 = 50, shape2 = 10, geom = "area", alpha = 0.5, fill = "#3498DB") %>%
gf_dist("beta", shape1 = 50, shape2 = 10)
It is much faster than the previous code, parameter alpha is obvious and it is relatively easy to combine many plots! Because of transparency, you can nicely see the overlap of both distributions.
I need to create a forestplot of high resolution. I used the forestplot() function from library(forestplot) to create my plot, and then attempted to use the tiff() function to create a high resolution image for publication. However, my image turned blank.
It works if I export directly from R but not as high resolution as it was supposed to.
library(forestplot)
df <- structure(list(
mean = c(NA, 0.22, 0.20, 0.27),
lower = c(NA, 0.05, 0.04, 0.01),
upper = c(NA, 0.95, 1.08, 9.12)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -4L),
class = "data.frame")
tabletext <- cbind(
c("", "Pooled", "Group 1", "Group 2"),
c("N", "4334", "3354", "980"),
c("HR (95% CI)", "0.22 (0.05, 0.95)", "0.20 (0.04, 1.08)", "0.27 (0.01, 9.12)"),
c("p-value", "0.042", "0.061", "0.467")
)
ggfp <- forestplot(tabletext,
df,
new_page = TRUE,
is.summary = c(TRUE, rep(FALSE, 3)),
clip = c(0, 2),
colgap = unit(5, "mm"),
line.margin = unit(2, "mm"),
lineheight = unit(1, "in"),
txt_gp = fpTxtGp(label = gpar(cex = 1),
ticks = gpar(cex = 1)),
align = c("l", "c", "c", "c"),
boxsize = 0.2,
xticks = seq(0, 2.0, 0.5),
zero = 1,
col = fpColors(box = "royalblue",
line = "darkblue"),
mar = unit(c(-1, 0.5, -2, 0.5), "in"))
tiff("forestplot.tiff", units = "in", width = 9, height = 7, res = 300)
ggfp
dev.off()
The file was created but it was a blank page
This works for me (output file is 17MB):
library(forestplot)
setwd("/path/to/directory/for/plot")
df <- structure(list(
mean = c(NA, 0.22, 0.20, 0.27),
lower = c(NA, 0.05, 0.04, 0.01),
upper = c(NA, 0.95, 1.08, 9.12)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -4L),
class = "data.frame")
tabletext <- cbind(
c("", "Pooled", "Group 1", "Group 2"),
c("N", "4334", "3354", "980"),
c("HR (95% CI)", "0.22 (0.05, 0.95)", "0.20 (0.04, 1.08)", "0.27 (0.01, 9.12)"),
c("p-value", "0.042", "0.061", "0.467")
)
tiff("forestplot.tiff", units = "in", width = 9, height = 7, res = 300)
forestplot(tabletext,
df,
new_page = TRUE,
is.summary = c(TRUE, rep(FALSE, 3)),
clip = c(0, 2),
colgap = unit(5, "mm"),
line.margin = unit(2, "mm"),
lineheight = unit(1, "in"),
txt_gp = fpTxtGp(label = gpar(cex = 1),
ticks = gpar(cex = 1)),
align = c("l", "c", "c", "c"),
boxsize = 0.2,
xticks = seq(0, 2.0, 0.5),
zero = 1,
col = fpColors(box = "royalblue",
line = "darkblue"),
mar = unit(c(-1, 0.5, -2, 0.5), "in"))
dev.off()
I would like to change the color of my error bars to different colors without changing the position of the points on my graph.
Here is a bit of my data:
df <- structure(
list(
yrmonth = structure(
c(
1483228800,
1483228800,
1483228800,
1485907200,
1485907200,
1485907200,
1488326400,
1488326400,
1488326400,
1491004800,
1491004800,
1491004800
),
class = c("POSIXct", "POSIXt"),
tzone = "UTC"
),
index = structure(
c(1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 5L),
.Label = c("N-S", "N-S", "E-W", "E-W", "OS"),
class = "factor"
),
N = c(2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1),
GDDLettuce = c(129, 141, 27, 150.5, 209, 87, 247.5,
243, 188, 223, 226.5, 170),
sd = c(
1.4142135623731,
4.24264068711928,
NA,
4.94974746830583,
65.0538238691624,
NA,
12.0208152801713,
8.48528137423857,
NA,
5.65685424949238,
0.707106781186548,
NA
),
se = c(1, 3, NA, 3.5, 46, NA, 8.5, 6, NA, 4, 0.5, NA),
ci = c(
12.7062047361747,
38.1186142085241,
NA,
44.4717165766114,
584.485417864036,
NA,
108.002740257485,
76.2372284170481,
NA,
50.8248189446988,
6.35310236808735,
NA
)
),
.Names = c("yrmonth", "index", "N", "data", "sd", "se", "ci"),
row.names = 31:42,
class = "data.frame"
)
I have my graph set up exactly the way I want it with error bars in the right locations:
ggplot(df, aes(x=yrmonth,y=data,colour=factor(index))) +
geom_line(size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se), width = 1000000, size = .5,
position = position_dodge(width = -300000))
When I add one color, the color of the bars change, but it removes all the width and dodge parameters that I put in:
ggplot(df, aes(x=yrmonth,y=data,colour=factor(index))) +
geom_line(size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se), colour = "black", width = 1000000, size = .5,
position = position_dodge(width = -300000))
I would like the E-W error bars to be a dark green and the N-S error bars to be a dark red. I would like the lines themselves to stay the same color. Most importantly I want the error bars to stay in there same locations. For some reason, every time I change the color the position of my error bars and lines changes.
A quick and easy solution would be
require(dplyr)
ggplot(df %>% mutate(errorColors = ifelse(index=="N-S","darkred",ifelse(index=="E-W","darkgreen",NA))), aes(x=yrmonth,y=data)) +
geom_line(aes(group=index,color=index),size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se,color=errorColors), width = 1000000, size = .5,
position = position_dodge(width = -300000))+scale_color_manual(breaks=c("E-W","N-S","OS"),values=c("darkgreen","darkred","green","red","blue"))
try add one more layer scale_color_manual in your first plot code like this:
ggplot(df, aes(x=yrmonth,y=data,colour=factor(index))) +
geom_line(size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se), width = 1000000, size = .5,
position = position_dodge(width = -300000))+
scale_color_manual(values = c('darkblue', 'darkgreen', 'darkred'))