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 registered here specifically for this purpose.
Basically I have two data frames that have the exact same information but from two different years.
Here the head() of one of the data frames:
species dbh_cm height_m f plot dbh_m ba
1 1 0.7 1.34 7.1627066 16 0.007 3.848451e-05
2 3 1.9 1.95 2.0018036 16 0.019 2.835287e-04
3 3 4.0 3.05 0.9120516 16 0.040 1.256637e-03
4 1 3.5 2.27 1.0072122 16 0.035 9.621128e-04
5 3 0.6 1.52 6.9312671 16 0.006 2.827433e-05
6 3 4.2 2.70 0.9406631 16 0.042 1.385442e-03
volume class Sp
1 0.0003693754 (0,5] Spruce
2 0.0011067593 (0,5] Larch
3 0.0034956596 (0,5] Larch
4 0.0021997474 (0,5] Spruce
5 0.0002978850 (0,5] Larch
6 0.0035187332 (0,5] Larch
For plotting the graphs for each of these I used:
ggplot(data=trees_b, aes(x=class, fill = Sp)) +
geom_bar(stat = "count") +
labs( x = "DBH classes [cm]", y = "Number of trees [n]", fill="Species") +
scale_x_discrete(labels=c("(0,5]" = "2.5","(5,10]" = "7.5", "(10,15]" = "12.5",
"(15,20]" = "17.5", "(20,25]" = "22.5", "(25,30]" = "27.5",
"(30,35]" = "32.5", "(35,40]" = "37.5", "(40,45]" = "42.5",
"(45,50]" = "47.5", "(50,55]" = "52.5", "(55,60]" = "57.5",
"(60,65]" = "62.5", "(65,70]" = "67.5","(70,75]" = "72.5",
"(75,80]" = "77.5", "(80,85]" = "82.5")) +
scale_fill_viridis(direction = -1, discrete = T) +
theme(axis.text.x = element_text( size = 15),
axis.text.y = element_text (size = 15),
axis.title = element_text(size = 15),
legend.text = element_text (size = 15),
legend.title = element_text (size = 16, face = "bold"))
I know the code is not the cleanest but it worked out perfectly for what I needed and that is this:
enter image description here
Now I want to basically combine the two graphs into one for comparison purposes, is there a way to do that?
One approach to combine your graphs would be to use faceting. To this end I use dplyr::bind_rows to bind your datasets by row and which makes it easy to add an identifier column to the data which could then be used as faceting variable:
Note: I also added a simple function to compute the class means.
trees_b <- trees_a
trees <- list(a = trees_a, b = trees_b) |>
dplyr::bind_rows(.id = "id")
library(ggplot2)
library(viridis)
#> Loading required package: viridisLite
class_mean <- function(x) {
sapply(stringr::str_extract_all(x, "\\d+"), function(x) mean(as.numeric(x)))
}
ggplot(data = trees, aes(x = class, fill = Sp)) +
geom_bar(stat = "count") +
labs(x = "DBH classes [cm]", y = "Number of trees [n]", fill = "Species") +
scale_x_discrete(labels = class_mean) +
scale_fill_viridis(direction = -1, discrete = T) +
theme(
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15),
axis.title = element_text(size = 15),
legend.text = element_text(size = 15),
legend.title = element_text(size = 16, face = "bold")
) +
facet_wrap(~id)
EDIT As you clarified in your comment you want a stacked and dodged bar chart. One approach to achieve that would be via the "facets that's don't look like facets" trick. The basic idea is to facet by the variable you mapped on x and instead map the faceting variable on x. Afterwards we use some styling via theme options to get rid of the faceting look. For more options have a look at ggplot2 - bar plot with both stack and dodge.
ggplot(data = trees, aes(x = id, fill = Sp)) +
geom_bar(stat = "count") +
labs(x = "DBH classes [cm]", y = "Number of trees [n]", fill = "Species") +
scale_fill_viridis(direction = -1, discrete = T) +
theme(
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15),
axis.title = element_text(size = 15),
legend.text = element_text(size = 15),
legend.title = element_text(size = 16, face = "bold")
) +
facet_wrap(~class, labeller = labeller(class = class_mean), strip.position = "bottom", nrow = 1) +
theme(strip.placement = "outside", strip.background.x = element_blank(), panel.spacing.x = unit(0, "pt"))
DATA
trees_a <- structure(list(
species = c(1L, 3L, 3L, 1L, 3L, 3L), dbh_cm = c(
0.7,
1.9, 4, 3.5, 0.6, 4.2
), height_m = c(
1.34, 1.95, 3.05, 2.27,
1.52, 2.7
), f = c(
7.1627066, 2.0018036, 0.9120516, 1.0072122,
6.9312671, 0.9406631
), plot = c(16L, 16L, 16L, 16L, 16L, 16L),
dbh_m = c(0.007, 0.019, 0.04, 0.035, 0.006, 0.042), ba = c(
3.848451e-05,
0.0002835287, 0.001256637, 0.0009621128, 2.827433e-05, 0.001385442
), volume = c(
0.0003693754, 0.0011067593, 0.0034956596, 0.0021997474,
0.000297885, 0.0035187332
), class = c(
"(0,5]", "(0,5]", "(0,5]",
"(0,5]", "(0,5]", "(0,5]"
), Sp = c(
"Spruce", "Larch", "Larch",
"Spruce", "Larch", "Larch"
)
), class = "data.frame", row.names = c(
"1",
"2", "3", "4", "5", "6"
))
I have the following dataset:
structure(list(Isodecoder = c("Val", "Leu", "Ile", "Arg", "Ser",
"Ala"), Anticodon = c("AAC", "AAG", "AAT", "ACG", "AGA", "AGC"
), baseMean = c(16330.2876073118, 280025.429470444, 47222.9145508434,
639520.228162813, 591.699871418142, 194550.678700214), log2FC = c(0.241812205124871,
0.062182487534649, -0.912898805851376, 0.414430653693951, -0.547252664766089,
-0.576581451007797), lfcSE = c(0.330123826005643, 0.0835105091511506,
0.193443262487333, 0.258705563545134, 0.211263611125761, 0.249830083859411
), stat = c(0.732489405719955, 0.744606734729653, -4.71920703834881,
1.60193947132354, -2.59037825705024, -2.30789439806721), pvalue = c(0.463869906720502,
0.45650949539292, 2.36765754572021e-06, 0.109168994996796, 0.00958705250629343,
0.0210050107216242), FDR = c(0.585940934804845, 0.585940934804845,
1.7165121174307e-05, 0.201542759994085, 0.030678568020139, 0.0591953931677063
), Label = c("Val-AAC", "Leu-AAG", "Ile-AAT", "Arg-ACG", "Ser-AGA",
"Ala-AGC"), wobble = c("AT_wobble", "AT_wobble", "AT_wobble",
"AT_wobble", "AT_wobble", "AT_wobble")), row.names = c(NA, 6L
), class = "data.frame")
and I am plotting these as barplots within a larger loop. my barplot function is:
tRNA_barplot <- ggplot(data = df2, aes(x = Label, y = log2FC, fill = wobble, label = ifelse(FDR < 0.05, "*", "ns")))+
geom_bar(stat = "identity")+
geom_text(vjust = 0, nudge_y = ifelse(df2$log2FC < 0, -1, 1), size = ifelse(df2$FDR < 0.05, 6, 4))+
xlab("Isoacceptor")+
ylab(expression(paste(Log[2],"FC",sep="")))+
#ylim(c(-5, 5))+
theme_bw()+
theme(axis.text.x = element_text(size = 12, angle = 45, hjust = 1), plot.margin = margin(0.5,0.5,0.5,2, "cm"), axis.title = element_text(size = 12))+
ggtitle(iso, "Fed vs Starved - tRNA LFCs")
I've used fill = wobble to colour by wobble position. in barplots where both AT_wobble and GC_wobble are present ... AT_wobble is coloured red and GC_wobble is coloured blue/turquoise. How do I ensure GC_wobble remain blue/turquoise in barplots where it is plotted alone.
by the way ... by blue and red I mean the standard R colour output when not specified
Attached are examples of what i am talking about:
Leu is perfect but I would like plots like Pro to remain blue/turquoise for GC_wobble.
Also, I've specified that all FDR > 0.05 should have ns printed ontop of the barplot [ifelse(FDR < 0.05, "*", "ns")]. Is there a way to print the actual FDR number to 4 decimal places? I've tried numerous ways but they're all really messy.
Thanks!
Here is one approach to the two part question:
Part 1: Using the scales package you can determine the code for any default ggplot colour. I've set this out explicitly in a separate line to make it obvious, you could simplify by including this directly in the call to scale_fill_manual
Part 2: print the actual FDR number using a call to geom_text. Note adjustment to y scale to allow FDR text to avoid clashing with the plot boundary.
Some other points:
a) geom_col() is simpler than geom_bar(stat = "identity")
b) the call to expression() does not need to include paste, check out ?plotmath
c) adjust asterisk size using an ifelse conditional statement for the call to size
library(ggplot2)
col_GC_wobble <- scales::hue_pal()(2)[[2]]
scales::hue_pal()(2)[2]
#> [1] "#00BFC4"
ggplot(df2, aes(x = Label, y = log2FC, fill = wobble))+
geom_col()+
geom_text(aes(label = ifelse(FDR < 0.05, "*", round(FDR, 4))),
vjust = ifelse(df2$log2FC < 0, 1, -0.2),
size = ifelse(df2$FDR < 0.05, 10, 4))+
scale_fill_manual(values = col_GC_wobble)+
scale_y_continuous(expand = expansion(mult = 0.1))+
xlab("Isoacceptor")+
ylab(expression(Log[2]~FC))+
theme_bw()+
theme(axis.text.x = element_text(size = 12, angle = 45, hjust = 1),
plot.margin = margin(0.5,0.5,0.5,2, "cm"),
axis.title = element_text(size = 12))+
ggtitle("Fed vs Starved - tRNA LFCs")
Created on 2021-09-18 by the reprex package (v2.0.0)
You need to add scale_fill_manual. Look below.
tRNA_barplot <- ggplot(data = df2, aes(x = Label, y = log2FC, fill = wobble, label = ifelse(FDR < 0.05, "*", "ns")))+
geom_bar(stat = "identity")+
geom_text(vjust = 0, nudge_y = ifelse(df2$log2FC < 0, -1, 1), size = ifelse(df2$FDR < 0.05, 6, 4))+
xlab("Isoacceptor")+
ylab(expression(paste(Log[2],"FC",sep="")))+
#ylim(c(-5, 5))+
theme_bw()+
theme(axis.text.x = element_text(size = 12, angle = 45, hjust = 1), plot.margin = margin(0.5,0.5,0.5,2, "cm"), axis.title = element_text(size = 12))+
scale_fill_manual(values = c("AT_wobble" = 5))
This relates to my previous question.
I have an xlsx file with this structure and data:
It can be generated in R with the following code:
data<-data.frame("Mat_art"=c("Apples", "Naners", "Apples", "Naners", "Apples", "Naners", "Apples", "Naners", "Apples", "Naners", "Apples", "Naners", "Apples", "Naners", "Apples", "Naners"), "CompIDinv"=c(17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10), "Comp"=c("Cheese", "Cheese", "Mayo", "Mayo", "Ketchup", "Ketchup", "Glue", "Glue", "Tofu", "Tofu", "Ranch", "Ranch", "Marmite", "Marmite", "Butter", "Butter"), "Prom"=c(1.15968339356004, 1.09598175499146, 0.606871622602421, 0, 0.477223208284233, 0, 1.52931048485049, 0.499586619837113, 1.33614656021619, 1.95359709169813, 1.22093637869439, 2.34963432630937, 1.35262980291428, 1.69298650050846, 1.35086700266383, 1.24031665670217), "infCI95"=c(0.775987209086803, 0.727123902187271, 0.388630354128953, 0, 0.406186682979503, 0, 1.1431692694034, 0.318904748424858, 1.19987305571909, 1.03758502964521, 1.11361766267652, 2.09487026135963, 1.24530044274135, 0.543063809010205, 0.993468721657989, 0.695707000558221), "supCI95"=c(1.54337957803327, 1.46483960779564, 0.825112891075889, 0, 0.548259733588963, 0, 1.91545170029758, 0.680268491249369, 1.47242006471328, 2.86960915375105, 1.32825509471225, 2.60439839125911, 1.4599591630872, 2.84290919200671, 1.70826528366967, 1.78492631284613), "Color"=c("4", "3", "2", "2", "2", "2", "4", "2", "4", "4", "4", "4", "4", "4", "4", "4"), "Etiqueta"=c("Immobilization", "Conservation", "Degradation", "Degradation", "Degradation", "Degradation", "Immobilization", "Degradation", "Immobilization", "Immobilization", "Immobilization", "Immobilization", "Immobilization", "Immobilization", "Immobilization", "Immobilization"))
But I always load it from file with read.xlsx. With this file, I produce the following plot:
The problem with this plot is that it inverts, in a seemingly random manner, the appearance of the dots for Apples and Naners (an their corresponding bars). I would like for Apples to ALWAYS come on top and Naners bellow. Thanks to #Zhiqiang Wang I now realize I could do it by inverting the order of the factors, if I were to generate the dataframe in R. But I never do this, I always import it from the Excel file, and would like to know how to force the order to produce the correct plot with this approach. The actual code I use is the following:
library(xlsx)
library(ggplot2)
data=read.xlsx("FILE_NAME.xlsx", "SHEET_NAME")
data$Comp<-as.factor(data$Comp)
data$Mat<-as.factor(data$Mat)
data$Mat_art<-as.factor(data$Mat_art)
data$Etiqueta<-as.factor(data$Etiqueta)
ggplot(data = data, aes(x = reorder(Comp,CompIDinv), y = Prom, ymin = infCI95, ymax = supCI95, colour = reorder(Etiqueta, Color), shape=Mat_art)) +
scale_shape_manual(values=c(16, 15)) +
geom_point(position = position_dodge(width = 0.75), size = 3.5) +
geom_errorbar(position = position_dodge(width = 0.75), width = 1) +
scale_colour_manual(values = c("#0072B2", "#009E73", "#F0E442", "#D55E00", "#CC79A7")) +
geom_hline(yintercept=1, linetype="dashed", color = "black", size=1) +
labs(x = "Dip", y = "Yummyness", colour = "Behavior", shape = "Material") +
coord_flip() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black") , axis.text=element_text(size=15), axis.title=element_text(size=20), legend.title=element_text(size=20), legend.text=element_text(size=15))
I think you have the same problem as your previous post, dealing with factor levels. I can only answer your question based on the reproducible examples provided by you.
It is more about data than ggplot. If you want to reorder a factor variable, try to reorder it before ggplot, unless there are some reasons not to do so. This way, you can check if reorder actually works. To fix your problem:
In your code: reorder(Etiqueta, Color) does not work and gives some warning messages. The graph is not ordered accordingly. Because your Color variable is character not numeric as required by the function reorder. You need to convert it to numeric.
Add m_levels <- sort(unique(data$Mat_art), decreasing = TRUE), and use m_levels to reorder Mat_art. I do not know why this is needed but it works.
data$Comp<-as.factor(data$Comp)
data$Mat<-as.factor(data$Mat)
data$Etiqueta<-as.factor(data$Etiqueta)
#added or modified
data$Color = as.numeric(data$Color)
m_levels <- sort(unique(data$Mat_art), decreasing = TRUE)
data$Mat_art<-factor(data$Mat_art, levels = m_levels)
ggplot(data = data, aes(x = reorder(Comp,CompIDinv),
y = Prom, ymin = infCI95,
ymax = supCI95,
colour = reorder(Etiqueta, Color),
shape=Mat_art)) +
scale_shape_manual(values=c(16, 15)) +
geom_point(position = position_dodge(width = 0.75), size = 3.5) +
geom_errorbar(position = position_dodge(width = 0.75), width = 1) +
scale_colour_manual(values = c("#0072B2", "#009E73", "#F0E442", "#D55E00", "#CC79A7")) +
geom_hline(yintercept=1, linetype="dashed", color = "black", size=1) +
labs(x = "Dip", y = "Yummyness", colour = "Behavior", shape = "Material") +
coord_flip() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black") , axis.text=element_text(size=15), axis.title=element_text(size=20), legend.title=element_text(size=20), legend.text=element_text(size=15))
Hi, I'm trying to make a plot of a survey question with a likert scale using ggplots. I need to help to organize the middle "neutral" values correctly. I have used two data frames, one for the left side "low_col", and one for the right side "high_col", both have the neutral value divided by 2. This is the script I used for the plot, and how the graph looks. I would highly appreciate all the advice to correct the order, and also all the help to add the percentages that I have in both data frames in a column named per. I hope someone can help me. Thanks
ggplot()+ geom_bar(data = high_col, mapping = aes(x=Q6, y=per, fill=col), position = "stack", stat = "identity")+ geom_bar(data= low_col, mapping = aes(x=Q6, y=-per, fill=col), position = "stack", stat = "identity")+ geom_hline(yintercept = 0, color=c("white"))+coord_flip() +scale_fill_identity("", labels = mylevels, breaks=legend.pal, guide="legend") + theme_fivethirtyeight() + theme(plot.title = element_text(size=14, hjust=0.5)) + theme(axis.text.y = element_text(hjust=0)) + theme(legend.position = "bottom")
The structure of the low_col and high_col is as follows:
For high_col:
dput(high_col)
structure(list(Q6 = c("General", "0", "1", "2", "General", "0", "1", "2", "3", "General", "0", "1", "2", "3"), Q75 = c("Ni satisfecho, ni insatisfecho", "Ni satisfecho, ni insatisfecho", "Ni satisfecho, ni insatisfecho", "Ni satisfecho, ni insatisfecho", "Satisfecho", "Satisfecho", "Satisfecho", "Satisfecho", "Satisfecho", "Totalmente satisfecho", "Totalmente satisfecho", "Totalmente satisfecho", "Totalmente satisfecho", "Totalmente satisfecho"), n = c(5, 1, 3, 1, 53, 25, 19, 7, 2, 104, 52, 35, 14, 3), per = c(1.48809523809524, 0.609756097560975, 2.58620689655172, 2.17391304347826, 31.547619047619, 30.4878048780487, 32.7586206896551, 30.4347826086956, 40, 61.9047619047619, 63.4146341463414, 60.3448275862069, 60.8695652173913, 60), col = c("#DFDFDF", "#DFDFDF", "#DFDFDF", "#DFDFDF", "#92C5DE", "#92C5DE", "#92C5DE", "#92C5DE", "#92C5DE", "#0571B0", "#0571B0", "#0571B0", "#0571B0", "#0571B0")), row.names = c(NA, -14L), class = c("tbl_df", "tbl", "data.frame"))
For low_col:
dput(low_col)
structure(list(Q6 = c("General", "0", "General", "0", "1", "2", "General", "0", "1", "2"), Q75 = structure(c(2L, 2L, 3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L), .Label = c("Totalmente insatisfecho", "Insatisfecho", "Ni satisfecho, ni insatisfecho"), class = "factor"), n = c(2, 2, 5, 1, 3, 1, 4, 2, 1, 1), per = c(1.19047619047619, 2.4390243902439, 1.48809523809524, 0.609756097560975, 2.58620689655172, 2.17391304347826, 2.38095238095238, 2.4390243902439, 1.72413793103448, 4.34782608695652), col = c("#F4A582", "#F4A582", "#DFDFDF", "#DFDFDF", "#DFDFDF","#DFDFDF", "#CA0020", "#CA0020", "#CA0020", "#CA0020")), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame")).
As a reference, I'm trying to follow two blogs where some individuals already did this kind of likert plots. In the first, it uses the color "col" as fill in the geom_bar, however, in my case the order is not working properly. And the result is the graph I've attached.
In the second blog, I used the following script, but I cannot change the colors, nor the order of the legend, as the labels appear in alphabetical order, and the colors are selected by default. Thanks in advance for all the insights, and info.
ggplot()+ geom_bar(data = high_col, aes(x=Q6, y=per, fill=Q75), position = position_stack(reverse = TRUE), stat = "identity") + geom_bar(data= low_col, aes(x=Q6, y=-per, fill=Q75), position = "stack", stat = "identity") +coord_flip() + theme_fivethirtyeight() + theme(plot.title = element_text(size=14, hjust=0.5)) + theme(axis.text.y = element_text(hjust=0)) + theme(legend.position = "bottom") + scale_y_continuous(breaks = seq(-100,100, 5), limits = c(-25, 100)) + scale_color_manual(labels=c("Totalmente insatisfecho", "Insatisfecho", "Ni satisfecho, ni insatisfecho", "Satisfecho", "Totalmente satisfecho"), values=legend.pal, guide="legend")+geom_text(data = pro_labels, mapping = aes(x=Q6, y=left, label=paste(round(left), "%", sep = "")), hjust=2, color="white", size=3, position = "stack")+geom_text(data = pro_labels, mapping = aes(x=Q6, y=center, label=paste(round(center), "%")), hjust=1, color="white", size=3, position = "stack")+geom_text(data = pro_labels, mapping = aes(x=Q6, y=right, label=paste(round(right), "%")), hjust=2, color="white", size=3, position = "stack")+geom_hline(yintercept = 0, color=c("grey")) + scale_colour_manual("", values = legend.pal, guide="legend")
Updated version:
Hi, I have been trying to work this out and with the following code I got the neutral value in the middle, yet the colors do not match.
ggplot()+ geom_bar(data = high_col, aes(x=Q6, y=per, fill=Q75), position = position_stack(reverse = TRUE), stat = "identity") + geom_bar(data= low_col, aes(x=Q6, y=-per, fill=Q75), position = "stack", stat = "identity") +coord_flip() + theme_fivethirtyeight() + theme(plot.title = element_text(size=14, hjust=0.5)) + theme(axis.text.y = element_text(hjust=0)) + theme(legend.position = "bottom") + scale_y_continuous(breaks = seq(-100,100, 5), limits = c(-25, 100))+geom_text(data = pro_labels, mapping = aes(x=Q6, y=left, label=paste(round(left), "%", sep = "")), hjust=2, color="white", size=3, position = "stack")+geom_text(data = pro_labels, mapping = aes(x=Q6, y=center, label=paste(round(center), "%")), hjust=1, color="white", size=3, position = "stack")+geom_text(data = pro_labels, mapping = aes(x=Q6, y=right, label=paste(round(right), "%")), hjust=2, color="white", size=3, position = "stack")+ geom_hline(yintercept = 0, color=c("grey"))+ scale_fill_discrete(labels= c("Totalmente insatisfecho", "Insatisfecho", "Ni satisfecho, ni insatisfecho", "Satisfecho", "Totalmente satisfecho"))
The result is the second graph attached here.