I used the dataset below to make a plot. However, I don't know how to scale the x-axis and make it look nice.
ggplot(data = ggplot_data, mapping = aes(x = Estimate, y = Phenotype, group = Estimate_type,color = Estimate_type))+
geom_pointrange(aes(xmin = `Lower CI`, xmax = `Upper CI`), position = position_dodge(width = 0.25)) +
coord_cartesian(xlim = c(2.0, 20.0))+
labs(color = "Estimate Type") +
ggtitle("Within- and Between-Family Prediction Estimates")
ggsave("Estimateplot.png", width = 15, height = 5)
Perhaps try changing x = Estimate to x = as.numeric(Estimate)? E.g.
library(ggplot2)
ggplot_data <- data.frame(...1 = c("ASD Within", "ASD Between", "ADHD Within", "ADHD Between"),
"Estimate" = c(0.08747, 0.0208, 0.1805, 0.09616),
"Lower CI" = c(0.015, -0.03, 0.11, 0.04),
"Upper CI" = c(0.15, 0.72, 0.24, 0.14),
"Phenotype" = c("Autism Score", "Autism Score",
"ADHD Score", "ADHD Score"),
"Estimate_type" = c("Within Family", "Between Family",
"Within Family", "Between Family"),
check.names = FALSE)
ggplot(data = ggplot_data, mapping = aes(x = as.numeric(Estimate), y = Phenotype, group = Estimate_type, color = Estimate_type))+
geom_pointrange(aes(xmin = `Lower CI`, xmax = `Upper CI`), position = position_dodge(width = 0.25)) +
#coord_cartesian(xlim = c(2.0, 20.0))+
labs(color = "Estimate Type") +
ggtitle("Within- and Between-Family Prediction Estimates")
Created on 2022-07-07 by the reprex package (v2.0.1)
Edit
Not sure if it's necessary, but you can also change the orientation of the keys in the legend using:
library(tidyverse)
ggplot_data <- data.frame(...1 = c("ASD Within", "ASD Between", "ADHD Within", "ADHD Between"),
"Estimate" = c(0.08747, 0.0208, 0.1805, 0.09616),
"Lower CI" = c(0.015, -0.03, 0.11, 0.04),
"Upper CI" = c(0.15, 0.72, 0.24, 0.14),
"Phenotype" = c("Autism Score", "Autism Score",
"ADHD Score", "ADHD Score"),
"Estimate_type" = c("Within Family", "Between Family",
"Within Family", "Between Family"),
check.names = FALSE)
# Custom Key Glyph
draw_key_hpointrange <- function(data, params, size) {
grid::grobTree(
draw_key_path(data, params, size),
draw_key_point(transform(data,
size = (data$size %||% 1.5) * 4),
params)
)
}
ggplot(data = ggplot_data, mapping = aes(x = as.numeric(Estimate), y = Phenotype, group = Estimate_type, color = Estimate_type))+
geom_pointrange(aes(xmin = `Lower CI`, xmax = `Upper CI`),
position = position_dodge(width = 0.25),
key_glyph = "hpointrange") +
#coord_cartesian(xlim = c(2.0, 20.0))+
labs(color = "Estimate Type") +
ggtitle("Within- and Between-Family Prediction Estimates")
Created on 2022-07-07 by the reprex package (v2.0.1)
Related
Here is the graph that I have as a basis:
color_two_groups_type_2 <- c("dark red", "black")
pd <- position_dodge(0.4)
hedonic_price_indices %>% ggplot(aes(x=year, y=index, group=factor(sample_sizes), color=factor(sample_sizes))) +
geom_line(linetype = "dashed", position = pd) +
geom_point(size = 0.5, position = pd) +
geom_errorbar(aes(ymin = index_lower_ci, ymax = index_upper_ci), width = 0.15, size = 0.25, colour="black", position = pd) +scale_y_continuous(breaks = c(0.5,1.0,1.5,2.0,2.5), limits = c(0.125, 2.85)) +
theme(legend.position="bottom", legend.margin=margin(0,0,0,0), legend.box.margin=margin(-20,0,0,0)) +
scale_color_manual(labels = c("Alternative", "Normal"), values = color_two_groups_type_2, guide = guide_legend(reverse = TRUE)) +
labs(title = "", x = "", y = "Index value (2000 = 1)", color = "") +
scale_x_discrete(breaks = c(1985,1990,1995,2000,2005,2010,2015,2020))
Now I would like to have two different line types.
desired_linetype <- c("dotted", "solid")
color_two_groups_type_2 <- c("dark red", "black")
pd <- position_dodge(0.4)
hedonic_price_indices %>% ggplot(aes(x=year, y=index, group=factor(sample_sizes), color=factor(sample_sizes))) +
#geom_line(linetype = "dashed", position = pd) +
geom_line(aes(linetype = sample_sizes), position = pd) +
scale_linetype_manual(values = desired_linetype) +
geom_point(size = 0.5, position = pd) +
geom_errorbar(aes(ymin = index_lower_ci, ymax = index_upper_ci), width = 0.15, size = 0.25, colour="black", position = pd) +
scale_y_continuous(breaks = c(0.5,1.0,1.5,2.0,2.5), limits = c(0.125, 2.85)) + theme(legend.position="bottom", legend.margin=margin(0,0,0,0), legend.box.margin=margin(-20,0,0,0)) +
scale_color_manual(labels = c("Alternative", "Normal"), values = color_two_groups_type_2, guide = guide_legend(reverse = TRUE)) +
labs(title = "", x = "", y = "Index value (2000 = 1)", color = "") +
scale_x_discrete(breaks = c(1985,1990,1995,2000,2005,2010,2015,2020))
Unfortunately, I have got two legends by now. By adding + guides(col = "none") (e.g. at the bottom), the left part of the legend gets removed:
And alternatively, by changing scale_linetype_manual(values = desired_linetype) to scale_linetype_manual(values = desired_linetype, guide="none"), the right part of the legend is gets removed:
However, I would like to have mixed version of these two legends. I.e. a legend that shows both the line type and the color. How could I obtain this result? (and I would prefer not to have a legend title ("sample sizes"), as in my initial graph).
I would be thankful for any suggestion!
Here is some code to reproduce the graphs:
hedonic_price_indices <- structure(list(estimate = c(-0.575412358998748, -0.52549627191954, -0.48635414326085, -0.732792998304216, -0.562889873546058, -0.913572700671539, -1.13936126077503, -1.08231133221031, -1.3515171997382, -0.94983790292841 ), lower_ci = c(-0.626714841953077, -0.584959417015897, -0.542829387483941, -0.790953736050918, -0.620938372048851, -1.02481824744291, -1.26017870739697, -1.17246349249945, -1.41331442736626, -1.01254016013769), upper_ci = c(-0.524109876044418, -0.466033126823183, -0.429878899037759, -0.674632260557514, -0.504841375043265, -0.802327153900171, -1.01854381415308, -0.992159171921177, -1.28971997211013, -0.887135645719133), year = c("1984", "1985", "1986", "1987", "1988", "1984", "1985", "1986", "1987", "1988"), estimate_exp = c(-0.437527119774759, -0.408738135115574, -0.38513598119696, -0.519435103003286, -0.430439275221177, -0.598911308640654, -0.679976631974547, -0.661188486027214, -0.741152760388594, -0.613196281876959), lower_ci_exp = c(-0.465655673667104, -0.442871528710716, -0.41889823785973, -0.546587846514592, -0.462560117662101, -0.641138316492387, -0.71639666004378, -0.69039670436256, -0.756664572496545, -0.636705020910341 ), upper_ci_exp = c(-0.407917843611993, -0.372513502931199, -0.349412123229172, -0.490656308062782, -0.3963986859341, -0.551715477774212, -0.63887958407625, -0.629224741409214, -0.724652122619944, -0.588166297456909), index = c(0.562472880225241, 0.591261864884426, 0.61486401880304, 0.480564896996714, 0.569560724778823, 0.401088691359346, 0.320023368025453, 0.338811513972786, 0.258847239611406, 0.386803718123041), index_lower_ci = c(0.534344326332896, 0.557128471289284, 0.58110176214027, 0.453412153485408, 0.537439882337899, 0.358861683507613, 0.28360333995622, 0.30960329563744, 0.243335427503455, 0.363294979089659), index_upper_ci = c(0.592082156388007, 0.627486497068801, 0.650587876770828, 0.509343691937218, 0.6036013140659, 0.448284522225788, 0.36112041592375, 0.370775258590786, 0.275347877380056, 0.411833702543091), sample_sizes = c("Normal", "Normal", "Normal", "Normal", "Normal", "Alternative", "Alternative", "Alternative", "Alternative", "Alternative")), row.names = c("normal_sale_1984", "normal_sale_1985", "normal_sale_1986", "normal_sale_1987", "normal_sale_1988", "foreclosure_1984", "foreclosure_1985", "foreclosure_1986", "foreclosure_1987", "foreclosure_1988"), class = "data.frame")
To merge your legends use the same labels and guide in both scale_color and scale_linetype and the same name in labs:
library(ggplot2)
library(dplyr)
desired_linetype <- c("dotted", "solid")
color_two_groups_type_2 <- c("dark red", "black")
pd <- position_dodge(0.4)
hedonic_price_indices %>%
ggplot(aes(x = year, y = index, group = factor(sample_sizes), color = factor(sample_sizes))) +
geom_line(aes(linetype = sample_sizes), position = pd) +
geom_point(size = 0.5, position = pd) +
geom_errorbar(aes(ymin = index_lower_ci, ymax = index_upper_ci),
width = 0.15, size = 0.25, colour = "black", position = pd
) +
scale_x_discrete(breaks = c(1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020)) +
scale_y_continuous(breaks = c(0.5, 1.0, 1.5, 2.0, 2.5), limits = c(0.125, 2.85)) +
scale_color_manual(
labels = c("Alternative", "Normal"),
values = color_two_groups_type_2,
guide = guide_legend(reverse = TRUE)
) +
scale_linetype_manual(
labels = c("Alternative", "Normal"),
values = desired_linetype,
guide = guide_legend(reverse = TRUE)
) +
labs(
title = "", x = "", y = "Index value (2000 = 1)",
color = "", linetype = ""
) +
theme(
legend.position = "bottom",
legend.margin = margin(0, 0, 0, 0),
legend.box.margin = margin(-20, 0, 0, 0)
)
I have this graph that I made using this code:
df3 <- data.frame(outcome=c("Any complication", "Cardiac complication",
"Vascular Complication","Vascular complication",
"Respiratory complication", "Infectious complication",
"Neurological complication"),
index=1:7,
effect=c(-.4, -.25, -.1, .1, .15, .2, .3),
lower=c(-.43, -.29, -.17, -.02, .04, .17, .27),
upper=c(-.37, -.21, -.03, .22, .24, .23, .33))
plot2 <- ggplot(data=df3, aes(y=index, x=effect, xmin=lower, xmax=upper))+
geom_point(shape="diamond", colour="royalblue4", size=5) +
geom_errorbarh(height=.2, colour="royalblue4") +
scale_y_continuous(breaks=1:nrow(df3), labels=df3$outcome) +
labs(title="Adjusted Relative Risk for Complications", x="Relative Risk", y = "Type of complication") +
geom_vline(xintercept=0, color='gray', linetype='dashed', alpha=.5) +
theme_minimal()+
plots_theme
But I would like to add the RR, the 95% confidence interval and some other things there, as shown here:
I could really use some help! Quite new in R here :(
To make it easier, I would borrow one of several R packages which can make forest plots. As a quick start, I use forestplot package here as an example:
library(tidyverse)
library(forestplot)
df3 %>%
mutate(ci = paste0(" (", lower, ", ", upper, ")")) %>%
arrange(-index) %>%
forestplot::forestplot(
labeltext = c(outcome, effect, ci),
mean = effect,
low = lower,
upper = upper,
size = 0.1,
graph.pos = 2,
vertices = TRUE,
xlab = "Relative Risk",
title="Adjusted Relative Risk for Complications") %>%
fp_add_header(
outcome = c("Outcome"),
effect = c("Estimate"),
ci = "95% (CI)") %>%
fp_set_style(box = "royalblue4", line = "royalblue4")
Edit
Just something different from your question, the Estimate values shown in the graph may not be relative risk but regression coefficient. If you would like to present relative risk, you could take an advantage of meta package:
library(meta)
df3 <- df3 %>% arrange(-index)
forest_df <-metagen(lower = lower,
upper = upper,
TE = effect,
data = df3,
sm = "RR")
forest(forest_df,
studlab = paste0(outcome),
layout = "JAMA",
common = FALSE,
hetstat = FALSE,
overall = FALSE)
Get work done with less code and journal format.
Here a way with geom_rect, geom_text and annotate.
library(ggplot2)
df3 <- data.frame(outcome=c("Any complication", "Cardiac complication",
"Vascular Complication","Vascular complication",
"Respiratory complication", "Infectious complication",
"Neurological complication"),
index=1:7,
effect=c(-.4, -.25, -.1, .1, .15, .2, .3),
lower=c(-.43, -.29, -.17, -.02, .04, .17, .27),
upper=c(-.37, -.21, -.03, .22, .24, .23, .33))
ggplot(data=df3, aes(y=index, x=effect, xmin=lower, xmax=upper))+
geom_point(shape="diamond", colour="royalblue4", size=5) +
geom_errorbarh(height=.2, colour="royalblue4") +
scale_y_continuous(breaks=1:nrow(df3), labels=df3$outcome) +
labs(title="Adjusted Relative Risk for Complications", x="Relative Risk", y = "Type of complication") +
geom_vline(xintercept=0, color='gray', linetype='dashed', alpha=.5) +
annotate("rect", xmin=.5, xmax= 1, ymin=0, ymax= 8, fill = "white")+
geom_text(aes(label = paste(effect, "(", lower, ",", upper,")")) ,
x= 0.5, hjust="left") +
scale_x_continuous(limits = c(-0.5, 1.0))+
annotate("text", label = "Estimate - 95% CI", x = 0.5, hjust="left", y= 8)+
theme_minimal() + theme()
And I am trying to do a chart like this one
... but instead of a pie chart I wanna do a Donut chart.
However I can't figure out how to do that. This is my chart until now:
My data:
Quantidade_de_ativos_por_setor = data.frame(
Setor = c("Outros","Lajes corporativas", "Logística", "Shoppings", "Híbridos", "Hotel", "Residencial", "Hospital", "Títulos e Val Mob"),
Ativos_por_setor = c(198, 155, 111, 92, 83, 28, 4, 3, 1),
Porcentagem_por_Setor = c(29.33, 22.96, 16.44, 13.63,12.30, 4.15, 0.59, 0.44, 0.15))
My code:
Quantidade_de_ativos_por_setor <- FIIS %>%
group_by(Setor)%>%
summarize(Ativos_por_setor = sum(Quantidade_de_Ativos))%>%
mutate(Porcentagem_por_Setor = (Ativos_por_setor/sum(Ativos_por_setor))*100)%>%
arrange(desc(Ativos_por_setor))
Quantidade_de_ativos_por_setor$Porcentagem_por_Setor <- round(Quantidade_de_ativos_por_setor$Porcentagem_por_Setor, digit=2)
Hsize<- 1.5
ggplot(Quantidade_de_ativos_por_setor, aes(x = Hsize, y = Ativos_por_setor, fill = Setor)) +
geom_col(color = "black") +
geom_text(aes(label = paste0("n = ", Ativos_por_setor, ", \n", Porcentagem_por_Setor, "%")), position = position_stack(vjust = 0.5 )) +
coord_polar(theta = "y") +
scale_fill_brewer(palette = "Dark2") +
xlim(c(0.1, Hsize + 0.5)) +
theme(panel.background = element_rect(fill = "white"),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank())
Thank you.
Here is a solution.
It uses a pipe and mutate to compute
More than the maximum 8 colors allowed by the palette "Dark";
coordinates for geom_text and geom_text_repel;
the labels to be displayed, inside the donut they have 3 lines of text, outside only one line.
The code is inspired in this R Graph Gallery post and on this R-bloggers post.
library(ggplot2)
library(ggrepel)
library(RColorBrewer)
library(scales)
library(dplyr)
colorcount <- nrow(Quantidade_de_ativos_por_setor)
getPalette <- colorRampPalette(brewer.pal(colorcount, "Dark2"))
Quantidade_de_ativos_por_setor %>%
mutate(fraction = Porcentagem_por_Setor/sum(Porcentagem_por_Setor),
ymax = cumsum(fraction),
ymin = c(0, head(ymax, n = -1)),
xlabel = ifelse(fraction > 0.04, 3.5, NA_real_),
xlabel_repel = ifelse(fraction < 0.04, 4.25, NA_real_),
ylabel = (ymax + ymin) / 2,
label = ifelse(fraction > 0.04,
paste(Setor, "\n n =", Ativos_por_setor, "\n", percent(fraction)),
paste0(Setor, ", n =", Ativos_por_setor, ", ", percent(fraction)))) %>%
ggplot(aes(ymax = ymax, ymin = ymin, xmax = 4, xmin = 3, fill = Setor)) +
geom_rect() +
geom_text(aes(x = xlabel, y = ylabel, label = label)) +
geom_text_repel(aes(x = xlabel_repel, y = ylabel, label = label)) +
scale_fill_manual(
labels = Quantidade_de_ativos_por_setor$Setor,
values = getPalette(colorcount)
) +
coord_polar(theta = "y") +
xlim(c(2, 4.5)) +
theme_void()
I wanted to visualize the bar graph in a additive way (waterfall plot, see below).
This is the data:
structure(list(Parameter = c("Driving", "Driver Behaviour", "Road Quality",
"Passenger load", "Speed", "Topography", "climate", "total"),
Values = c(0.8, 0.2, 0.2, 0.2, 0.24, 0.5, 0.8, 2.82)),
row.names = c(NA, -8L), class = "data.frame")
# Parameter Values
# 1 Driving 0.80
# 2 Driver Behaviour 0.20
# 3 Road Quality 0.20
# 4 Passenger load 0.20
# 5 Speed 0.24
# 6 Topography 0.50
# 7 climate 0.80
# 8 total 2.82
This is the output im trying to produce. Is there any way i can do it in R?
Still in need of some polishing but in principle your watefall chart can be achieved like so:
BTW: Because of rounding errors your data gives a total of 2.94 instead of 2.82.
d <- structure(list(Parameter = c("Driving", "Driver Behaviour", "Road Quality",
"Passenger load", "Speed", "Topography", "climate", "total"),
Values = c(0.8, 0.2, 0.2, 0.2, 0.24, 0.5, 0.8, 2.82)),
row.names = c(NA, -8L), class = "data.frame")
library(ggplot2)
library(dplyr)
# Prepare the dataset
d1 <- d %>%
mutate(ymax = cumsum(Values),
ymin = lag(ymax, default = 0),
xmax = as.numeric(factor(Parameter, levels = Parameter)),
xmin = lag(xmax, default = 0),
x = (xmin + xmax) / 2,
y = (ymin + ymax) / 2,
label = Values,
label_color = "white",
) %>%
# Get the total right
mutate(ymin = ifelse(Parameter == "total", 0, ymin),
ymax = ifelse(Parameter == "total", Values, ymax),
y = ifelse(Parameter %in% c("Driving", "total"), Values + .2, y),
label = case_when(
Parameter %in% c("Driving") ~ paste0("Best Case\n", Values),
Parameter %in% c("total") ~ paste0("Worst Case\n", Values),
TRUE ~ as.character(Values)),
label_color = ifelse(Parameter %in% c("Driving", "total"), "black", "white"))
ggplot(d1, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)) +
geom_rect(fill = "#E40019") +
geom_text(aes(x = x, y = y, label = label, color = label_color), show.legend = FALSE) +
scale_x_continuous(breaks = seq(.5, 7.5, 1), labels = d1$Parameter) +
scale_color_manual(values = c(white = "white", black = "black")) +
theme_bw()
Created on 2020-06-16 by the reprex package (v0.3.0)
I am currently trying to add a secondary axis using the recently introduced function sec.axis in ggplot2. This function works well with scatter/bar plots, but not for polar plot: In the following code, the name for the second y-axis appears, but not the axis.
Is there any workaround or option, that I have not figured out?
require(ggplot2)
set.seed(40);
Location <- data.frame(Winkel = round(runif(1000, 0, 24), 0))
Location$BAD <- Location$Winkel %in% c(seq(7, 18))
Abschnitte <- c(0:24)
polar <- data.frame(Winkel2 = c(1.5, 2.34, 1.2, 3.45, 1.67, 2.61, 1.11, 13.2),
value = c(0.1, 0.03, 0.02, 0.015, 0.01, 0.04, 0.09, 0.06))
ggplot(Location, aes(x = Winkel, fill = BAD, y = (..count..)/sum(..count..))) +
geom_histogram(breaks = seq(0,24), colour = "black") +
coord_polar(start = 0) + theme_minimal() +
scale_fill_brewer(type = "seq", palette = 3) +
ylab("Percentual allocation time") +
ggtitle("") +
scale_x_continuous("", limits = c(0, 24), breaks = Abschnitte, labels = Abschnitte) +
scale_y_continuous(labels = scales::percent,
sec.axis = sec_axis(~.*5, name = "mean direction")) +
geom_segment(data = polar, aes(x = Winkel2, y = 0, xend = Winkel2, yend = value, fill = NA),
arrow = arrow(angle = 30, type = "closed", length = unit(0.3, "cm")))
As #henrik mentioned in the comments, this is a bug. It's been patched and is available if you use the development version from GitHub (i.e., devtools::install_github("tidyverse/ggplot2")).
Here's the example after the patch:
require(ggplot2)
#> Loading required package: ggplot2
set.seed(40);
Location <- data.frame(Winkel = round(runif(1000, 0, 24), 0))
Location$BAD <- Location$Winkel %in% c(seq(7, 18))
Abschnitte <- c(0:24)
polar <- data.frame(Winkel2 = c(1.5, 2.34, 1.2, 3.45, 1.67, 2.61, 1.11, 13.2),
value = c(0.1, 0.03, 0.02, 0.015, 0.01, 0.04, 0.09, 0.06))
ggplot(Location, aes(x = Winkel, fill = BAD, y = (..count..)/sum(..count..))) +
geom_histogram(breaks = seq(0,24), colour = "black") +
coord_polar(start = 0) + theme_minimal() +
scale_fill_brewer(type = "seq", palette = 3) +
ylab("Percentual allocation time") +
ggtitle("") +
scale_x_continuous("", limits = c(0, 24), breaks = Abschnitte, labels = Abschnitte) +
scale_y_continuous(labels = scales::percent,
sec.axis = sec_axis(~.*5, name = "mean direction")) +
geom_segment(data = polar, aes(x = Winkel2, y = 0, xend = Winkel2, yend = value, fill = NA),
arrow = arrow(angle = 30, type = "closed", length = unit(0.3, "cm")))
#> Warning: Ignoring unknown aesthetics: fill