Scale fill gradient using absolute values - r

In the following chart, I would like a gradient to be applied at an absolute value level, rather than relative values. For example, rows I and G should be the same color of red as their values are -75 and 75, respectively. By the same token, rows F and E should be the same shade of green as their values are -15 and 15, respectively. Can anyone tell me how I would do this?
library(dplyr)
library(ggplot2)
data.frame(grp = LETTERS[1:10],
vals = c(0.11, 0.39, -0.06, 0.42, 0.15, -0.15, 0.75, -0.02, -0.75, 0.00)) %>%
ggplot(aes(x = vals, y = grp, fill = vals)) +
geom_col() +
scale_fill_gradient(low = "green", high = "red")

You could simply use fill = abs(vals)
data.frame(grp = LETTERS[1:10],
vals = c(0.11, 0.39, -0.06, 0.42, 0.15, -0.15, 0.75, -0.02, -0.75, 0.00)) %>%
ggplot(aes(x = vals, y = grp, fill = abs(vals))) +
geom_col() +
scale_fill_gradient(low = "green", high = "red")

Related

Plotting of the mean in boxplot before axis log transformation in R

I want to include the mean inside the boxplot but apparently, the mean is not located at the position where it is supposed to be. If I calculate the mean from the data it is 16.2, which would equal 1.2 at the log scale. I tried various things, e.g., changing the position of the stat_summary function before or after the transformation but this does not work.
Help is much appreciated!
Yours,
Kristof
Code:
Data:
df <- c(2e-05, 0.38, 0.63, 0.98, 0.04, 0.1, 0.16, 0.83, 0.17, 0.09, 0.48, 4.36, 0.83, 0.2, 0.32, 0.44, 0.22, 0.23, 0.89, 0.23, 1.1, 0.62, 5, 340, 47) %>% as.tibble()
Output:
df %>%
ggplot(aes(x = 0, y = value)) +
geom_boxplot(width = .12, outlier.color = NA) +
stat_summary(fun=mean, geom="point", shape=21, size=3, color="black", fill="grey") +
labs(
x = "",
y = "Particle counts (P/kg)"
) +
scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x)))
The mean calculated by stat_summary is the mean of log10(value), not of value. Below I propose to define a new function my_mean for a correct calculation of the average value.
library(ggplot2)
library(dplyr)
library(tibble)
library(scales)
df <- c(2e-05, 0.38, 0.63, 0.98, 0.04, 0.1, 0.16,
0.83, 0.17, 0.09, 0.48, 4.36, 0.83, 0.2, 0.32, 0.44,
0.22, 0.23, 0.89, 0.23, 1.1, 0.62, 5, 340, 47) %>% as.tibble()
# Define the mean function
my_mean <- function(x) {
log10(mean(10^x))
}
df %>%
ggplot(aes(x = 0, y = value)) +
geom_boxplot(width = .12, outlier.color = NA) +
stat_summary(fun=my_mean, geom="point", shape=21, size=3, color="black", fill="grey") +
labs(
x = "",
y = "Particle counts (P/kg)"
) +
scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
labels = trans_format("log10", math_format(10^.x)))

Need help to display legend and in similar color code to the data

I am visualizing a time-series plot using ggplot2 and trying to combine the legend. I have tried many options but in not yet gotten my desired output. In one plot the lines are missing the color coding and in the other, the chart is missing the legend. My desired output is to have a chart with the legend and the color scheme being the same.
Here is the script where the lines are missing the color-coding;
library(tidyverse)
deviation <- read_csv("C:/Users/JohnWaweru/Documents/Thesis/Data/yearly_CSVs/Turkana_new/2018_new.csv")
deviation %>% ggplot() +
geom_line(aes(x = as.Date(Month), y = Upper_curve, col = 'red'), linetype = 2) +
geom_line(aes(x = as.Date(Month), y = Lower_curve, col = 'red'), linetype = 2) +
geom_line(aes(x = as.Date(Month), y = Mean_NDVI, col = 'red'), linetype = 1) +
geom_line(aes(x = as.Date(Month), y = NDVI_2018, col = 'green'), linetype = 1) +
scale_color_manual(name = 'Legend',
values = c('Mean_NDVI'= 'red', 'NDVI_2018' = 'green', 'Upper_curve' = 'red', 'Lower_curve' = 'red'),
labels = c('Mean_NDVI', 'NDVI_2018', 'Upper_curve','Lower_curve')) +
ylim(0.2, 0.6) +
scale_x_date(date_labels = "%b", date_breaks = "1 month") +
ylab(label = "NDVI") +
xlab(label = "Month") +
ggtitle("NDVI Deviation 2018") ```
Here is the Sample data I am working with;
structure(list(Month = structure(c(18262, 18293, 18322, 18353, 18383, 18414), class = "Date"),
Mean_NDVI = c(0.26, 0.23, 0.25, 0.34, 0.36, 0.32),
NDVI_2018 = c(0.22, 0.23, 0.23, 0.41, 0.46, 0.32),
Mean_Std = c(0.01, 0.01, 0.01, 0.02, 0.02, 0.02),
Std_2018 = c(0.01, 0.01, 0.03, 0.03, 0.04, 0.03),
Upper_curve = c(0.27, 0.24, 0.26, 0.36, 0.38, 0.34),
Lower_curve = c(0.25, 0.22, 0.24, 0.32, 0.34, 0.3)),
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))
Setting literal colours only works outside the aes() function or when you use scale_colour_identity(). Most of the time when you want to label individual line layers, you can set aes(..., colour = "My legend label").
library(ggplot2)
deviation <- structure(list(
Month = structure(c(18262, 18293, 18322, 18353, 18383, 18414), class = "Date"),
Mean_NDVI = c(0.26, 0.23, 0.25, 0.34, 0.36, 0.32),
NDVI_2018 = c(0.22, 0.23, 0.23, 0.41, 0.46, 0.32),
Mean_Std = c(0.01, 0.01, 0.01, 0.02, 0.02, 0.02),
Std_2018 = c(0.01, 0.01, 0.03, 0.03, 0.04, 0.03),
Upper_curve = c(0.27, 0.24, 0.26, 0.36, 0.38, 0.34),
Lower_curve = c(0.25, 0.22, 0.24, 0.32, 0.34, 0.3)),
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame")
)
ggplot(deviation) +
geom_line(aes(x = Month, y = Upper_curve, colour = 'Upper_curve'), linetype = 2) +
geom_line(aes(x = Month, y = Lower_curve, colour = 'Lower_curve'), linetype = 2) +
geom_line(aes(x = Month, y = Mean_NDVI, colour = 'Mean_NDVI'), linetype = 1) +
geom_line(aes(x = Month, y = NDVI_2018, colour = 'NDVI_2018'), linetype = 1) +
scale_color_manual(
name = 'Legend',
values = c('Mean_NDVI'= 'red', 'NDVI_2018' = 'green',
'Upper_curve' = 'red', 'Lower_curve' = 'red'),
# Setting appropriate linetypes
guide = guide_legend(
override.aes = list(linetype = c(2,1,1,2))
)
) +
ylim(0.2, 0.6) +
scale_x_date(date_labels = "%b", date_breaks = "1 month") +
ylab(label = "NDVI") +
xlab(label = "Month") +
ggtitle("NDVI Deviation 2018")
Created on 2021-08-05 by the reprex package (v1.0.0)

Single option in scale_fill_stepsn changes color rendering in legend

I'm using ggplot's scale_fill_stepsn to generate a map with a stepped scale. When I use the option n.breaks the colors specified render properly in the legend. n.breaks calculates the breaks based on the number of breaks specified. However, when I use the option to manually specify the breaks with the same number of breaks used in n.breaks, the color rendering in the legend changes and are not rendered properly.
This does not make sense. Can this be fixed such that the legend colors in the second example look like that in the first?
library(urbnmapr)
library(ggplot2)
library(dplyr)
library(ggthemes)
# Set colors
red <- c(0.67, 0.75, 0.84, 0.92, 1, 1, 0.8, 0.53, 0, 0, 0, 0)
green <- c(0.25, 0.4, 0.56, 0.71, 0.86, 1, 1, 0.95, 0.9, 0.75, 0.6, 0.48)
blue <- c(0.11, 0.18, 0.25, 0.33, 0.4, 0.45, 0.4, 0.27, 0, 0, 0, 0)
# Obtain county polygon data
states_sf <- get_urbn_map(map = "states", sf = TRUE)
counties_sf <- get_urbn_map(map = "counties", sf = TRUE)
# Assign random values of data to each count
counties_sf$value = runif(length(counties_sf$county_fips), min=-3.0, max=3.0)
# Remove AK and HI - lower 48 only
states_sf <- states_sf[!(states_sf$state_abbv %in% c("HI","AK")),]
counties_sf <- counties_sf[!(counties_sf$state_abbv %in% c("HI","AK")),]
# Plot county-level data with a discrete legend
data_levels <- c(-3,-1.5, -0.8, -0.5, -0.25,-0.1,0.1,0.25,0.5,.8,1.5,3)
level_colors <- rgb(red, green, blue)
length(data_levels)
length(level_colors)
# First version -
counties_sf %>%
ggplot() +
# Overlay State Outlines
# Plot county data and fill with value
geom_sf(mapping = aes(fill = value), color = NA) +
geom_sf(data = states_sf, fill = NA, color = "black", size = 0.25) +
# Remove grid lines from plot
coord_sf(datum = NA) +
#
# THE FIRST OPTION of scale_fill_stepsn IS WHERE THEY ARE DIFFERENT
#
scale_fill_stepsn(n.breaks=12, colors=level_colors, limits=c(-3,3),
labels=scales::label_number(accuracy=0.1)) +
labs(title='This Data is Completely Random',
fill ='The Legend') +
theme_map() +
theme(legend.position = "bottom",
legend.key.width=unit(1.5,"cm"),
legend.box.background = element_rect(color="black", size=2),
legend.title = element_text(face = "bold"),
legend.spacing = unit(0.25,"cm"),
legend.justification = "center",
plot.title=element_text(hjust=0.5)) +
guides(fill = guide_colorsteps(even.step=TRUE,
title.position="top",
title.hjust = 0.5,
frame.colour = 'black',
barwidth=unit(250,'points'),
axis.linewidth=unit(3,'points')))
This yields:
#
# Second version -
counties_sf %>%
ggplot() +
# Overlay State Outlines
# Plot county data and fill with value
geom_sf(mapping = aes(fill = value), color = NA) +
geom_sf(data = states_sf, fill = NA, color = "black", size = 0.25) +
# Remove grid lines from plot
coord_sf(datum = NA) +
#
# THE FIRST OPTION of scale_fill_stepsn IS WHERE THEY ARE DIFFERENT
# replaced n.breaks with breaks option
#
scale_fill_stepsn(breaks=data_levels, colors=level_colors, limits=c(-3,3),
labels=scales::label_number(accuracy=0.1)) +
labs(title='This Data is Completely Random',
fill ='The Legend') +
theme_map() +
theme(legend.position = "bottom",
legend.key.width=unit(1.5,"cm"),
legend.box.background = element_rect(color="black", size=2),
legend.title = element_text(face = "bold"),
legend.spacing = unit(0.25,"cm"),
legend.justification = "center",
plot.title=element_text(hjust=0.5)) +
guides(fill = guide_colorsteps(even.step=TRUE,
title.position="top",
title.hjust = 0.5,
frame.colour = 'black',
barwidth=unit(250,'points'),
axis.linewidth=unit(3,'points')))
This version yields the following image. Notice the colors in the legend are now different.
The first option evenly spaces out 12 breaks from -3 to 3 which then exactly coincide with your colours. Whereas the second option sets unevenly spaced values with the exact colours falling in between some of the breaks. The (hidden) gradient is still evenly spaced though. To have the gradient spaced as your breaks, you need to set the values argument of the scale. Simplified example below.
library(ggplot2)
df <- data.frame(
x = runif(100),
y = runif(100),
z = runif(100, -3, 3)
)
level_colors <- rgb(
red = c(0.67, 0.75, 0.84, 0.92, 1, 1, 0.8, 0.53, 0, 0, 0, 0),
green = c(0.25, 0.4, 0.56, 0.71, 0.86, 1, 1, 0.95, 0.9, 0.75, 0.6, 0.48),
blue = c(0.11, 0.18, 0.25, 0.33, 0.4, 0.45, 0.4, 0.27, 0, 0, 0, 0)
)
data_levels <- c(-3,-1.5, -0.8, -0.5, -0.25,-0.1,0.1,0.25,0.5,.8,1.5,3)
ggplot(df, aes(x, y, fill = z)) +
geom_point(shape = 21) +
scale_fill_stepsn(breaks=data_levels, colors=level_colors, limits=c(-3,3),
values = scales::rescale(data_levels),
labels=scales::label_number(accuracy=0.1))
Created on 2021-04-08 by the reprex package (v1.0.0)

R - ggplot2 Legend not appearing for line graph [duplicate]

This question already has answers here:
Add legend to ggplot2 line plot
(4 answers)
Closed 4 years ago.
I know this question has been asked before, and I've looked at many of the links, but none of them seem to be helping my case.
I'm plotting a line graph for 4 lines of different colors. But I can't get the legend to appear.
I've read that I need to put the color attribute in the aes part of the graph. That hasn't been successful either.
I have a data frame of four column, and 1000 rows. Here's a small reproducible example of what my data looks like, and how I'd like to plot it.
library(ggplot2)
vec1 <- c(0.1, 0.2, 0.25, 0.12, 0.3, 0.7, 0.41)
vec2 <- c(0.5, 0.4, 0.3, 0.55, 0.12, 0.12, 0.6)
vec3 <- c(0.01, 0.02, 0.1, 0.5, 0.14, 0.2, 0.5)
vec4 <- c(0.08, 0.1, 0.54, 0.5, 0.1, 0.12, 0.3)
df <- data.frame(vec1, vec2, vec3, vec4)
df_plot <- ggplot() +
geom_line(data = df, color = "black", aes(x = c(1:7), y = df[,1], color =
"black")) +
geom_line(data = df, color = "blue", aes(x = c(1:7), y = df[,2], color =
"blue")) +
geom_line(data = df, color = "green", aes(x = c(1:7), y = df[,3], color =
"green")) +
geom_line(data = df, color = "yellow", aes(x = c(1:7), y = df[,4], color
= "yellow")) +
xlab("x axis") +
ylab("y axis") +
ggtitle("A random plot") +
theme(legend.title = element_text("Four lines"), legend.position =
"right")
(Also, did SO change the process of indenting code? Before, I could just press Ctrl + K to indent the entire block of code. But I can't do that anymore. Ctrl+K puts the cursor in my URL box for some reason)
I'd like ti it print the legend to the right of the graph.
First: I see a lot of people here creating data frames by first creating individual vectors. I don't know where this practice originated but it isn't necessary:
df1 <- data.frame(vec1 = c(0.1, 0.2, 0.25, 0.12, 0.3, 0.7, 0.41),
vec2 = c(0.5, 0.4, 0.3, 0.55, 0.12, 0.12, 0.6),
vec3 = c(0.01, 0.02, 0.1, 0.5, 0.14, 0.2, 0.5),
vec4 = c(0.08, 0.1, 0.54, 0.5, 0.1, 0.12, 0.3))
Next: your data is in "wide" form. ggplot2 works better with "long" form: one column for variables, another for their values. You can get to that using tidyr::gather. While we're at it, we can use dplyr::mutate to add the x variable:
library(dplyr)
library(tidyr)
library(ggplot2)
df1 %>%
gather(Var, Val) %>%
mutate(x = rep(1:7, 4))
Now we can plot. With the data in this form, there is no need to use a separate geom for each variable and aes() automatically takes care of colors and legends. You can specify custom colors using scale_color_manual. I don't know that yellow or green are great choices, but here it is:
df1 %>%
gather(Var, Val) %>%
mutate(x = rep(1:7, 4)) %>%
ggplot(aes(x, Val)) +
geom_line(aes(color = Var)) +
scale_color_manual(values = c("black", "blue", "green", "yellow"))
The key is having your data in the correct format, and understanding how that allows aes to map variables to chart properties.

Repeating categories on lattice plot (likert function in R)

I am a novice R user and am trying to create a plot using the likert function from the HH package. My problem seems to come from from repeating category labels. It is easier to show the issue:
library(HH)
responses <- data.frame( Subtable= c(rep('Var1',5),rep('Var2',4),rep('Var3',3)),
Question=c('very low','low','average','high','very high', '<12', '12-14', '15+',
'missing', '<25','25+','missing'), Res1=as.numeric(c(0.05, 0.19, 0.38, 0.24, .07,
0.09, 0.73, 0.17, 0.02, 0.78, 0.20, 0.02)), Res2=as.numeric(c(0.19, 0.04, 0.39,
0.22, 0.06, 0.09, 0.50, 0.16, 0.02, 0.75, 0.46, 0.20)))
likert(Question ~ . | Subtable, responses,
scales=list(y=list(relation="free")), layout=c(1,3),
positive.order=TRUE,
between=list(y=0),
strip=FALSE, strip.left=strip.custom(bg="gray97"),
par.strip.text=list(cex=.6, lines=3),
main="Description of Sample",rightAxis=FALSE,
ylab=NULL, xlab='Percent')
Unfortunately it creates strange spaces that aren't really there, as exhibited in the bottom panel of the following plot:
This seems to come from the repeated category 'missing'. My actual data has several repeats (e.g., 'no', 'other') and whenever they are included I get these extra spaces. If I run the same code but remove the repeated categories then it runs properly. In this case that means changing 'responses' in the code above to responses[! responses$Question %in% 'missing',].
Can someone tell me how to create the graph using all the categories, without getting the 'extra' spaces? Thanks for your help and patience.
-Z
R 3.0.2
HH 3.0-3
lattice 0.20-24
latticeExtra 0.6-26
Here is a solution using ggplot2 to create the graphic
library(ggplot2)
responses <-
data.frame(Subtable = c(rep('Var1',5), rep('Var2',4), rep('Var3',3)),
Question = c('very low','low','average','high','very high',
'<12', '12-14', '15+', 'missing', '<25','25+',
'missing'),
Res1 = as.numeric(c(0.05, 0.19, 0.38, 0.24, .07, 0.09, 0.73,
0.17, 0.02, 0.78, 0.20, 0.02)),
Res2 = as.numeric(c(0.19, 0.04, 0.39, 0.22, 0.06, 0.09, 0.50,
0.16, 0.02, 0.75, 0.46, 0.20)),
stringsAsFactors = FALSE)
responses$Subtable <- factor(responses$Subtable, levels = paste0("Var", 1:3))
responses$Question <-
factor(responses$Question,
levels = c("missing", "25+","<25", "<12", "12-14", "15+",
"very low", "low", "average", "high", "very high"))
ggplot(responses) +
theme_bw() +
aes(x = 0, y = Question) +
geom_errorbarh(aes(xmax = 0, xmin = Res1, color = "red")) +
geom_errorbarh(aes(xmin = 0, xmax = -Res2, color = "blue")) +
facet_wrap( ~ Subtable, ncol = 1, scale = "free_y") +
scale_color_manual(name = "",
values = c("red", "blue"),
labels = c("Res1", "Res2")) +
scale_x_continuous(breaks = c(-0.5, 0, 0.5),
labels = c("0.5", "0", "0.5")) +
ylab("") + xlab("Percent") +
theme(legend.position = "bottom")

Resources