I’m trying to plot data in a dual y-axis bar plot via ggplot…not sure what it wrong with my code here as I’ve checked it against many other examples. The dataframe (mun_ndvi_lst_long) is already in long format as follows:
mun_ndvi_lst_long <- data.frame(Municipality = c("City of Miami", "City of Miami",
"Opa-Locka", "Opa-Locka", "Coral Gables", "Coral Gables", "South Miami",
"South Miami", "Doral", "Doral", "Miami Beach", "Miami Beach",
"Pinecrest", "Pinecrest", "Florida City", "Florida City", "Homestead",
"Homestead", "Hialeah", "Hialeah", "Miami Shores", "Miami Shores"
), Variable = c(25.02, 0.181, 25.8, 0.183, 22.67, 0.275, 24.13,
0.276, 24.57, 0.188, 23.71, 0.157, 23.36, 0.322, 23.1, 0.28,
23.99, 0.262, 26.08, 0.163, 24.05, 0.259), Type = c("LST", "NDVI",
"LST", "NDVI", "LST", "NDVI", "LST", "NDVI", "LST", "NDVI", "LST",
"NDVI", "LST", "NDVI", "LST", "NDVI", "LST", "NDVI", "LST", "NDVI",
"LST", "NDVI"))
Here is my code:
ggplot(mun_ndvi_lst_long,
aes(x = Municipality,
y = Variable,
fill = Type)) +
geom_col(position = "dodge") +
scale_y_continuous(sec.axis = sec_axis(~ . * 0.015, name = "NDVI")) +
labs(y = "LST (°C)")
I end up with the following, where it looks like NDVI is still corresponding to the left y-axis rather than the right:
>Solution :
You would need to transform your Variable values with the inverse of the transformation in sec_axis:
library(dplyr)
library(ggplot2)
mun_ndvi_lst_long %>%
mutate(Variable = ifelse(Type == "NDVI", Variable / 0.015, Variable)) %>%
ggplot(aes(x = Municipality, y = Variable, fill = Type)) +
geom_col(position = "dodge") +
scale_y_continuous(sec.axis = sec_axis(~ . * 0.015, name = "NDVI")) +
labs(y = "LST (°C)")
However, this isn’t ideal visualization practice in most cases. I would recommend facets with separate axes instead:
ggplot(
mun_ndvi_lst_long,
aes(x = Municipality, y = Variable, fill = Type)
) +
geom_col(show.legend = FALSE) +
facet_wrap(vars(Type), ncol = 1, scales = "free") +
labs(y = "LST (°C)")


