these are my codes:
ggplot(summer.months, aes(x = month, y = Temp_mean, linetype = position, color = canopy, fill = position)) +
geom_boxplot() +
theme_bw() +
ggtitle(" Temperature changes in elevated and lying deadwood in summer under different canopies") +
labs(y = "temperature values(C°)", x = "months") +
scale_fill_manual(values = c("white", "white", "green", "black"))
my professor said:
i have to put number of objects on the legend on the graph and put the legend on the upper right-hand corner of the graph & make the legend bigger.
put the months in a chronological order like 11,12,1,2,3,4.. ( put the names of the months in the graph instead of numbers)
i created a basic ggplot but the problem is i can´t do the changes that they want from me cuz the names and order of the objects are so in my excel data.
A dput(head(summer.months)) might be sufficient. Anyway, here's an example using internal dataset mpg for illustrating few adjustments:
library(tidyverse)
## changing variable for x-Axis into ordered factor - this is a bit of a workaround. If using dates,
## it is better to use datatype date and adjust axis labels accordingly
my_mpg <- mpg %>%
mutate(class = factor(class, levels = c("compact", "midsize", "suv", "2seater", "minivan", "pickup", "subcompact"), ordered = TRUE))
ggplot(my_mpg, aes(x = class, y = hwy, linetype = class, colour = fl, fill = drv)) +
geom_boxplot() +
scale_fill_manual(values = c("white", "white", "green", "black")) +
## using subtitle to add information about the dataset
labs(title = "title", subtitle = paste("#lines: ", nrow(mpg))) +
theme_bw() +
theme(legend.justification = "top", ## move legend to top
legend.text = element_text(size = 10), ## adjust text sizes in legend
legend.title = element_text(size =10),
legend.key.size = unit(20, "pt"), ## if required: adjust size of legend keys
plot.subtitle = element_text(hjust = 1.0)) ## shift subtitle to the right
You might find further hints in ggplot2 reference and the ggplot2 book.
Related
I am trying to make the following changes to the ggplot below (partly illustrated in the picture provided):
change shading legend to show economic cycle (shaded is a recession, no shade is an expansion)
add additional legend to show economic variables (green is 'CLI' and red is 'Inflation Expectations")
The code so far looks like this:
A <- ggplot(Alldata, aes(Date)) +
geom_tile(aes(alpha = Recession, y = 1),
fill = "grey", height = Inf) +
scale_alpha_continuous(range = c(0, 1), breaks = c(0, 1))+
geom_line(aes(y = stdINFEX), col = 'blue', size = .8)+
ylab('')+
theme( axis.text.y=element_blank(), #remove y axis labels
axis.ticks.y=element_blank() #remove y axis ticks
)
A
B <- A + geom_line(aes(y = CLI), col = 'green', size = .8)
B
Maybe this is what you are looking for:
You could set the labels for legend entries via the labels argument of the scale, e.g. using a named vector you could assign a label Expansion to the value "0"
To get a legend for your lines you have to map on aesthetics, i.e. move color=... inside of aes(). Note that using color names inside aes() is meaningless. Therefore I would suggest to use meaningful labels. You could then set your desired colors via scale_color_manual.
Finally, to set the labels for your legends you could make use of labs()
As you provided no example data (see how to make a minimal reproducible example) I make use of the ggplot2::economics dataset as example data:
library(ggplot2)
set.seed(123)
economics$Recession <- 0
economics$Recession[sample(1:nrow(economics), 100)] <- 1
ggplot(economics, aes(date)) +
geom_tile(aes(alpha = Recession, y = 1),
fill = "grey", height = Inf
) +
scale_alpha_continuous(range = c(0, 1),
breaks = c(0, 1),
labels = c("0" = "Expansion", "1" = "Recession")) +
geom_line(aes(y = psavert, color = "psavert"), size = .8) +
geom_line(aes(y = uempmed, color = "uempmed"), size = .8) +
scale_color_manual(values = c(psavert = "blue", uempmed = "green")) +
labs(y = NULL, alpha = "Economic Cycle", color = "Economic Variable") +
theme(
axis.text.y = element_blank(),
axis.ticks.y = element_blank()
)
I am trying to synchronise the order of the legend with the bar plots in this picture. As you can see, "All Countries" label is the first in my legend yet in the bar plot I have it as last. I wish I correct the barplot and have the black bar plot labeled as 'All Countries" as first. Is there a way to fix it but with the caveat I keep the colour pallete since it is for partial 'colour blinded' people.
this is my code
cbbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442",
"#0072B2", "#D55E00", "#CC79A7", "#CC6600")
plot_adjusted_rates <- ggplot2::ggplot(adj_sympt_forcats,
ggplot2::aes(symptoms, age_standardise_rate_in_sympt, country)) +
ggplot2::coord_flip() +
ggplot2::geom_bar(ggplot2::aes(fill = country), width = 0.4,
position = position_dodge(width = 0.5), stat = "identity") +
ggplot2::scale_fill_manual(values = cbbPalette)
I have followed another example here: ggplot legend: change order of the automatic legend
Yet it does not correct it and messed my colour pallets. Does someone know how to correct this? Data can't be provided due to confidentiality of it.
I have solved the issue with:
"
scale_fill_manual( values = cols,
guide = guide_legend(reverse = TRUE))
"
The plot itself is here:
plot_adjusted_rates <- ggplot2::ggplot(adj_comorb_forcats,
ggplot2::aes(comorbidities, age_standardise_rate_in_comorb, country)) +
ggplot2::coord_flip() +
ggplot2::geom_bar(ggplot2::aes(fill = country), width = 0.4,
position = position_dodge(width = 0.5), stat = "identity") +
ggplot2::scale_fill_manual( values = cols,
guide = guide_legend(reverse = TRUE)) +
ggplot2::labs(
x = "Pre-existing conditions", y = "Percentage") +
ggplot2::theme(axis.title.y = ggplot2::element_text(margin = ggplot2::margin(t = 0, r = 21, b = 0, l = 0)),
plot.title = ggplot2::element_text(size = 12, face = "bold"),
plot.subtitle = ggplot2::element_text(size = 10),
legend.position = "bottom" , legend.box = "horizontal") +
ggplot2::theme_bw()
plot_adjusted_rates
With the answer given above - I get my country variable with NA. Therefore, I believe it is better use the scale_fill_manual parameters given by ggplot2
And visual plot is right here:
As observed, the legend is in sync with bar charts colour.
It would have helped if you had given a part of your data. But, I think your problem is related to reversing labels. You can use "rev" to change order of label.
I am using iris database to show the use of "rev"
library(ggplot2)
theme_set(
theme_classic()
)
Usual plot:
plot1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
geom_boxplot(aes(color = Species)) +
scale_color_manual(values = c("#000000", "#E69F00", "#56B4E9"))
plot1
#Reverse the order
iris$Species <- factor(iris$Species, levels = rev(levels(iris$Species)))
New plot:
ggplot(iris, aes(x = Species, y = Sepal.Length)) +
geom_boxplot(aes(color = Species)) +
scale_color_manual(values = c("#000000", "#E69F00", "#56B4E9"))
As you can see in figures the labels have changed.
You can explore "rev" based on your requirement.
I'm trying to create some boxplots in R. I've been using both ggboxplot and ggplot. This is my code and output so far:
ggboxplot:
ggboxplot(shp_PA#data, x = "hei_1998to2007_cat", y = "adjrate.2008to2017",
xlab = "Hazardous Exposure Index Jenks",
ylab = "Lung Cancer Incidence Rate",
color = "red",
add = c("jitter", "mean"),
add.params = list(color = "black", shape=20))
ggplot:
shp_PA#data %>%
ggplot(aes(x=hei_1998to2007_cat, y=adjrate.2008to2017)) +
geom_boxplot(colour = "red") +
geom_jitter(color="black", size=0.75) +
stat_summary(fun=mean, geom="point", shape=4, size=3, color="black") +
xlab("Hazardous Exposure Index Jenks") +
ylab("Lung Cancer Incidence Rate")
My main interest right now is in putting a legend on each boxplot that has the symbol used to depict the mean, and the word "Mean" next to it. In base R, its as simple as putting something like
legend("topright", legend=c("Mean"),pch=5, col="red")
but I can't figure it out in ggboxplot or ggplot. Most of the things I've seen online discuss modifying a legend that is already present.
One other thing I'm wondering how to do is specific to ggboxplot. I want to be able to make the color and shape of the jitter points different from the symbol for the mean. I've tried changing the add.params code to
add.params = list(color = c("black", "blue"), shape=c(20,4))
but I get the error
Error: Aesthetics must be either length 1 or the same as the data (213): shape and colour
Any help is greatly appreciated!
Edit: Add reproducible example using iris dataset in R
ggboxplot:
ggboxplot(iris, x = "Species", y = "Sepal.Length",
color = "red",
add = c("jitter", "mean"),
add.params = list(color = "black", shape=20))
ggplot:
ggplot(data=iris, aes(x=Species, y=Sepal.Length)) +
geom_boxplot(colour = "red") +
geom_jitter(color="black", size=0.75) +
stat_summary(fun=mean, geom="point", shape=4, size=3, color="black")
Again, I'd like to add a legend with the symbol used to depict the mean and the word "Mean", and be able to use ggboxplot to have the color and shape of the jitter and mean to be different.
Its a bit of a non-standard way to use ggplot, but you can do something like this.
add a legend with the symbol used to depict the mean and the word "Mean"
Map different shapes to geom_jitter and stat_summary using aes. Control those shapes using scale_shape_manual
have the color and shape of the jitter and mean to be different
Use color to change the colors for the jitter points and mean point, and use override.aes to change the colors in the legend.
ggplot(data=iris, aes(x=Species, y=Sepal.Length)) +
geom_boxplot(colour = "red") +
geom_jitter(size=1, color = 'green', aes(shape = 'all data')) +
stat_summary(fun=mean, geom="point", size=3, color = 'black', aes(shape = 'mean')) +
scale_shape_manual(values = c(20, 4)) +
guides(shape = guide_legend(override.aes = list(color = c('green', 'black'))))
Another similar answer here: https://stackoverflow.com/a/5179731/12400385
Welcome to SO!
Adding custom labels to ggplot2 is notoriously difficult, and I believe this is by design. All legends are controlled by the arguments placed in aes and scale_*_[continuoues|discrete|manual]. If we don't want to start learning how to grob (likely spending several hours) we can however achieve the desired output by
Adding are statistic to the data itself
Create a column indicating which is the statistic and which is data points
Abuse that we can subset the data directly in our geom_* function to create a specific layer for jitter and non-jittered points, and set the shape in the aestethics of these layers
Customize the marks using scale_shape_manual (or scale_shape_discrete).
Using the mtcars dataset as an example (and dplyr for piping) we can obtain something very similar to ggboxplot
library(ggplot2)
library(dplyr)
data(mtcars)
# Setup data with mean instead of using stat_summary
mtcars %>%
select(cyl, hp) %>%
group_by(cyl) %>%
summarize(hp = mean(hp)) %>%
bind_cols(stat = factor(rep('mean', 3))) %>%
bind_rows(mtcars %>%
select(cyl, hp) %>%
bind_cols(stat = rep('data', nrow(mtcars)))) %>%
# Create ggplot
ggplot(aes(x = factor(cyl), y = hp)) +
geom_boxplot(colour = 'red') +
# Jitter based on subset of data. Do the same for geom_point (means)
## Note that to only plot a subset I pass a function to data that "filters" the data.
geom_jitter(data = function(.data)filter(.data, stat == 'data'),
aes(shape = stat), color = 'black') +
# Add mean to the point and change shape into something we like.
geom_point(data = function(.data)filter(.data, stat == 'mean'),
aes(shape = stat), size = 2.5) +
## Use scale_shape_manual to change shape into something i like.
scale_shape_manual(values = c('mean' = 8, 'data' = 16)) +
# Fix the plot theme to be similar to ggboxplot
theme(panel.grid = element_line(colour = NA),
panel.background = element_rect(fill = "#00000000"),
axis.line.x = element_line(colour = 'black'),
axis.line.y = element_line(colour = 'black'),
axis.text = element_text(size = 11),
legend.position = 'bottom'
) +
# Remove label from the legend if wanted
labs(shape = NULL)
I have been trying to display a legend on a choropleth plot but finding the R docuemntation for legend a bit difficult to get my head around. Been reading it for a few hours now.
I see that the following gets a legend:
library(rnaturalearth)
world <- rnaturalearth::ne_countries(scale='medium',returnclass = 'sf')
class(world)
plot(world[,"adm0_dif"])
But the following, does not:
plot(world[,"adm0_dif"], col=sf.colors(n = nrow(world), alpha=0.5))
In the R help age for plot for sf object it states:
"Specifying col suppresses plotting the legend key."
So, I wonder what is the simplest way to get the default legend back if that is all I want.
I use ggplot more than I do base R plot so I am not sure how to add the legend back with base R. Additionally, I am not familiar with the rnaturalearth package and data so all I've done is replicate your plot with ggplot and add a legend. I am not sure if this is the legend you want but all I've done is make the exact same plot with ggplot and added a legend. You can then customise the legend if it's not what you are looking for.
library(ggplot2)
ggplot(data = world) +
geom_sf(aes(fill = 1:nrow(world))) +
scale_fill_viridis_c(name = "", alpha = 0.5, option = "plasma", trans = "sqrt") +
theme_classic()
For side by side plots of multiple variables we can use the gridExtra package.
library(gridExtra)
plot1 <- ggplot(data = world) +
geom_sf(aes(fill = 1:nrow(world))) +
scale_fill_viridis_c(name = "", alpha = 1, option = "plasma", trans = "sqrt") +
ggtitle("adm0_dif")+
theme(plot.title = element_text(hjust = 0.5),
panel.background = element_rect(fill = "white", colour = "white"))
plot2 <- ggplot(data = world) +
geom_sf(aes(fill = labelrank)) +
scale_fill_viridis_c(name = "", alpha = 1, option = "plasma", trans = "sqrt") +
ggtitle("labelrank") +
theme(plot.title = element_text(hjust = 0.5),
panel.background = element_rect(fill = "white", colour = "white"))
grid.arrange(plot1, plot2, ncol=2)
For plotting variables that are not coded by number, like featurecla, use scale_fill_manual instead like so
plot_fea <- ggplot(data = world) +
geom_sf(aes(fill = featurecla), show.legend = F) +
scale_fill_manual(name = "", values = c("mediumaquamarine"))+
ggtitle("featurecla") +
theme(plot.title = element_text(hjust = 0.5),
panel.background = element_rect(fill = "white", colour = "white"))
plot_fea
Note I've only supplied value ("mediumaquamarine") to values in scale_fill_manual because it only contains one unique variable. The number of colours passed to value has to match the number of unique variables in the column.
I want to create a boxplot with ggplot2 and I'd like to organize the plot in the order of the data frame, e.g.
I know that R organize the boxplot alphabetically. How can I:
Organize the X axis in the order Taste - Color - Capacity
Switch the boxes, i.e. first the green and then the orange, instead orange and green
Switch the legend order too, first NaCl and then O_{2}
library(ggplot2)
library(readxl)
Chemical <- rep(c("NaCl", "Al2"), times = 3, each = 4)
Quality <- rep(c("Taste", "Color of package", "Capacity"), times = 1, each = 8)
Accepted <- seq(0, 100, by = 100/23)
DF <- data.frame(Chemical, Quality, Accepted)
ggplot(DF, aes(x = Quality, y = Accepted, fill = Chemical)) +
geom_boxplot() +
scale_fill_manual(values = c("orange", "green"),
labels = expression("Al"[2], "NaCl")) +
xlab("") +
theme(legend.position = "top", legend.title = element_blank())
You have different methods to control the output. A quick solution would be:
ggplot(DF, aes(x = Quality, y = Accepted, fill = Chemical)) +
geom_boxplot() +
scale_fill_manual(values = c("green", "orange"),
labels = expression("Al"[2], "NaCl")) +
xlab("") +
theme(legend.position = "top", legend.title = element_blank()) +
guides(fill=guide_legend(reverse=TRUE)) +
scale_x_discrete(limits=c("Taste", "Color of package", "Capacity"))
Simply with the argument guides(fill=guide_legend(reverse=TRUE)), manually altering the order of the colors and fixing a specific order on the X axis with scale_x_discrete is achieved.
It is also possible to reorder the levels with DF$Quality <- factor (DF$Quality, levels = c ("Taste", "Color of package", "Capacity")) and achieve the same result without use scale_x_discrete().