This question already has answers here:
Add legend to ggplot2 line plot
(4 answers)
Closed 3 years ago.
p = ggplot() +
geom_line(data = Month_time, aes(x = Month, y = CarrierDelay), color = "red") +
geom_line(data = Month_time, aes(x = Month, y = WeatherDelay), color = "purple") +
geom_line(data = Month_time, aes(x = Month, y = NASDelay), color = "yellow") +
geom_line(data = Month_time, aes(x = Month, y = SecurityDelay), color = "green") +
geom_line(data = Month_time, aes(x = Month, y = LateAircraftDelay), color = "blue") +
xlab('Month') +
ylab('Delay Types [min]')
print(p)
Q How do you change the X-axis the Month to be just 1, 2, 3, 4 ...?
Q Also how do you add the label for each graph?
you can use scale_x_continuous. Also, you can get the desired plot by specifying the data source once at the beginning:
ggplot(month_time) +
geom_line(aes(x = Month, y = WeatherDelay), color = "purple") +
geom_line(aes(x = Month, y = NASDelay), color = "yellow") +
scale_x_continuous(breaks = 1:12)
Here, a sample of code that should re-organize your data to be ready to be plot by ggplot2:
library(tidyr)
library(dplyr)
library(ggplot2)
Month_subset = Month_time %>% select(., Month, CarrierDelay, WeatherDelay, NASDelay, SecurityDelay, LateAircraftDelay) %>%
pivot_longer(-Month,names_to = "Conditions", values_to = "Value")
ggplot(Month_subset, aes(x = Month, y = Value, color = Conditions)) +
geom_line() +
ylab("Delay Types [min]") +
scale_x_continuous(breaks = 1:12)
Basically, using dplyr and tidyr, we are going to select columns of interest then, re-organise the data in a long format using pivot_longer. And finally, we are going to plot everything in once using ggplot2. Like that, each of your conditions will be plot with a different color and a legend will be added mentioning each labels.
Warning this code is based on what I understand of what you are trying to do, but I can't verify it since you are not provding a reproducible example of your dataset. If you are adding one in your question, I will be happy to test my code and update it based on your real data
Related
I have three lots of data I want to plot together: two geom_line() over the top of one stacked geom_bar(). All of that is over a time series, with a bar and two line values for each year.
The data looks something like this:
df <- data.frame(year = rep(1:5, each = 3),
cat = c("small", "med", "large"),
count = rep(sample(1:10, 5)),
line1 = rep(sample(30000:40000, 5), each = 3),
line2 = rep(sample(200:300, 5), each = 3))
It's easy enough to plot all three together, but I don't want to show the y-axis label for the bars. Instead, I want the left axis to show one line and the right to show the other. I want the plot to look something like this:
but to have the left axis show the line1 value (i.e. the 30000:40000 value). How would I go about including the two line axes, but still showing the bars across the whole height of the plot?
library(ggplot2)
ggplot(data = df, aes(x=year)) +
geom_bar(aes(y = count, x = year, fill = cat), position = "fill", stat="identity") +
geom_line(aes(y = line1/max(line1))) +
geom_line(aes(y = line2/max(line2)), color = "red") +
scale_y_continuous(sec.axis = sec_axis(~.*max(df$line2), name = "line2 (red)"))
Simply adding the geom_bar() after a two-axis line plot results in the bars not showing, because the scale of the lines data is far beyond that of the proportional (0-1) bar data:
ggplot(data = df, aes(x=year)) +
geom_line(aes(y = line1)) +
geom_line(aes(y = line2*100), color = "red") +
scale_y_continuous(sec.axis = sec_axis(~./100, name = "line2 (red)")) +
geom_bar(aes(y = count, x = year, fill = cat), position = "fill", stat="identity")
I'd like these axes, but still show the bars:
Could do it with dplyr calculations in line:
library(dplyr); library(ggplot2)
ggplot(data = df, aes(x=year)) +
geom_col(data = df %>% group_by(year) %>%
mutate(share = count / sum(count) * max(df$line1)),
aes(y = share, x = year, fill = cat)) +
geom_line(aes(y = line1)) +
geom_line(aes(y = line2*100), color = "red") +
scale_y_continuous(sec.axis = sec_axis(~./100, name = "line2 (red)"))
I want to create a black and white plot using ggplot2, where the data is plotted by category using a combination of lines and points. However, the legend only shows the point shape, with no line running through it, unless I add color to the plot.
Here is some example data to illustrate the problem with:
## Create example data
set.seed(123)
dat <- data.frame(
time_period = rep(1:4, each = 3),
category = rep(LETTERS[1:3], 4),
y = rnorm(12)
)
Here is an example of a color plot, so you can see how I want the legend to look:
library(ggplot2)
## Generate plot with color
ggplot(data = dat, mapping = aes(x = time_period, y = y, color = category)) +
geom_line(aes(group = category)) +
geom_point(aes(shape = category), size = 2) +
theme_bw()
However, if I move to grayscale (which I need to be able to do), the line running through the point in the legend disappears, which I'd like to avoid:
## Generate plot without color
ggplot(data = dat, mapping = aes(x = time_period, y = y)) +
geom_line(aes(group = category)) +
geom_point(aes(shape = category), size = 2) +
theme_bw()
How can I add a line through the point symbols in the legend with a grayscale plot?
I would suggest this approach:
#Plot
ggplot(data = dat, mapping = aes(x = time_period, y = y,group = category,shape = category)) +
geom_line(color='gray',show.legend = T) +
geom_point(size = 2) +
theme_bw()
Output:
I want to create a customized legend that distinguishes two plotted geoms using appropriate shape and color. I see that guide_legend() should be involved, but my legend is presented with both shapes overlayed one on the other for both components of the legend. What is the right way to build these individual legend components using distinct shapes and colors? Thank you.
library(dplyr)
df <- tibble(year=seq(2010,2020,1),
annualNitrogen=seq(100,200,10),
annualPotassium=seq(500,600,10))
ggplot() +
geom_point(data = df, aes(x = year, y = annualNitrogen, fill="green"), shape=24, color="green", size = 4) +
geom_point(data = df, aes(x = year, y = annualPotassium, fill="blue"), color="blue", shape=21, size = 4) +
guides(fill = guide_legend(override.aes = list(color=c("green", "blue"))),
shape = guide_legend(override.aes = list(shape=c(21, 24)))
) +
scale_fill_manual(name = 'cumulative\nmaterial',
values = c("blue"="blue" , "green"="green" ),
labels = c("potassium" , "nitrogen") ) +
theme_bw() +
theme(legend.position="bottom")
Here it helps to transform to "long" format which is more in line with how ggplot is designed to be used when separating factor levels within a single time series.
This allows us to map shape and color directly, rather than having to manually assign different values to multiple plotted series, like you do in your question.
library(tidyverse)
df %>%
pivot_longer(-year, names_to = "element") %>%
ggplot(aes(x=year, y = value, fill = element, shape = element, color = element)) +
geom_point(size = 4)+
scale_color_manual(values = c("green", "blue"))
Put your df into a long format that ggplot likes with tidyr::gather. You should only use one geom_point for this, you don't need separate geoms for separate variables. You can then specify the shape and variable in one call to geom_point.
df <- tibble(year=seq(2010,2020,1),
annualNitrogen=seq(100,200,10),
annualPotassium=seq(500,600,10))
df <- tidyr::gather(df, key = 'variable', value='value', annualNitrogen, annualPotassium)
ggplot(df) +
geom_point(aes(x = year, y = value, shape = variable, color = variable)) +
scale_color_manual(
name = 'cumulative\nmaterial',
values = c(
"annualPotassium" = "blue",
"annualNitrogen" = "green"),
labels = c("potassium" , "nitrogen")) +
guides(shape = FALSE)
I created a new data set using tidyr:
library(tidyverse)
##Create some fake data
set.seed(3)
data <- tibble(
year = 1991:2020,
One = 11:40,
Two = 31:60,
Three = 61:90,
)
##Gather the variables to create a long dataset
new_data <- data %>%
gather(model, value, -year)
##plot the data
ggplot(new_data, aes(x = year, y = value, fill=model)) +
geom_bar(stat = "identity",position = "stack")+
geom_rangeframe() +
theme_tufte()
The Problem is that the y-axis is not at the correct length:
Adding a facet_grid to the code:
# facet_grid(~model)
I also tried adding
scale_y_continuous(limits = c(0, 150))
however it did not work.
I als tried adding a fake dataset which contains the range from min to max of my real data:
data2 <- tibble(
year = 1991:2020,
bmsum = dummy = c(11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,90)
)
new_data2 <- data2 %>%
gather(model, value, -year)
ggplot(new_data, aes(x = year, y = value, fill=model)) +
geom_bar(stat = "identity",position = "stack")+
geom_rangeframe(data=new_data2) +
facet_grid(~model)+
theme_pubclean()
There's nothing wrong with the axis, and this is nothing to do with the stacked plot. You're using ggthemes::geom_rangeframe(), which, if you view the description, creates:
Axis lines which extend to the maximum and minimum of the plotted data.
If you don't want those, don't use them. Your call to theme_tufte() is removing the background breaks, making it look like there's no axis.
You can put the lines back in after your theme_tufte() call by adding another call to theme() with an axis.line argument:
ggplot(new_data, aes(x = year, y = value, fill = model)) +
geom_bar(stat = "identity", position = "stack")+
theme_tufte() +
theme(axis.line = element_line(color = "black", size = 1))
This question already has answers here:
Add legend to "geom_bar" using the ggplot2 package
(2 answers)
Closed 5 years ago.
I'm new to ggplot, so hopefully this is an easy question. I've made a stacked barplot with colours for each segment given in col:
a <- data.frame(var = rep(seq(1:2),2), val = seq(1:4))
col <- c('red', 'blue', 'green', 'red')
ggplot(a, aes(x = var, y = val)) +
geom_bar(stat = 'identity', fill = col)
which looks like this:
how do I add a legend to the plot? I tried
+ scale_fill_manual(name = 'legend', breaks = seq(1:4), values = col)
You were close!
Move fill = col to aes:
library(ggplot2)
a <- data.frame(var = rep(seq(1:2),2), val = seq(1:4))
col <- rainbow(n = 4)
ggplot(a, aes(x = var, y = val, fill = col)) +
geom_bar(stat = 'identity') +
scale_fill_manual(values = col)
You have to put it within aes as col is variable that you want to map to specific aesthetic (in this case fill).