0

I have a contour plot with gradient colour using geom_raster, which is ok.

However, when I try to Yeo-Johnson transform the y-axis scale, the color gradient shows colored bands with interspaced white bands instead of a continuous gradient. The problem also occurs with geom_tile.

Any idea about what is happening and how to solve this problem?

Thanks for help

No transformation of y-axis scale:

library(ggplot2)
library(geomtextpath)
library(ggfx)
library(scales)

ggplot(data = dat, aes(x = x0, y = y0, fill = resp)) +
  geom_raster() +
  scale_x_continuous(breaks = c(0,15,30,45,60,75,90), labels=c(0,15,30,45,60,75,90)) +
  scale_y_continuous(breaks = c(0.1,10,20,30,40,50,60,70,80,90,100,110), labels=c(0.1,10,20,30,40,50,60,70,80,90,100,110)) +
  with_outer_glow(geom_textcontour(aes(z = resp), linetype = NA), colour = 'white', expand = 3, sigma = 1) +
  geom_textcontour(aes(z = resp), textcolour = NA) +
  scale_fill_gradientn(
    colours = c("red2", "white", "blue2"),
    values = scales::rescale(c(min(dat$resp), intercept, max(dat$resp))),
    limits = c(7, 15),
    guide=guide_colourbar(reverse = TRUE)) +
  labs(fill = "resp") +
  ylab("y0  (no transformation)") + xlab("x0")

enter image description here

Yeo-Johnson transformation of y-axis scale (not ok):

ggplot(data = dat, aes(x = x0, y = y0, fill = resp)) +
  scale_x_continuous(breaks = c(0,15,30,45,60,75,90), labels=c(0,15,30,45,60,75,90)) +
  scale_y_continuous(breaks = c(0.1,10,20,30,40,50,60,70,80,90,100,110), labels=c(0.1,10,20,30,40,50,60,70,80,90,100,110), trans = yj_trans(0.69)) +
  geom_tile() +
  with_outer_glow(geom_textcontour(aes(z = resp), linetype = NA), colour = 'white', expand = 3, sigma = 1) +
  geom_textcontour(aes(z = resp), textcolour = NA) +
  scale_fill_gradientn(
    colours = c("red2", "white", "blue2"),
    values = scales::rescale(c(min(dat$resp), intercept, max(dat$resp))),
    limits = c(7, 15),
    guide=guide_colourbar(reverse = TRUE)) +
  labs(fill = "resp") +
  ylab("y0  (Yeo-Johnson transformation)") + xlab("x0")

enter image description here

Data:

dat <-
structure(list(x0 = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 8.214, 8.214, 8.214, 8.214, 8.214, 8.214, 8.214, 8.214, 
8.214, 8.214, 8.214, 8.214, 8.214, 8.214, 8.214, 14.429, 14.429, 
14.429, 14.429, 14.429, 14.429, 14.429, 14.429, 14.429, 14.429, 
14.429, 14.429, 14.429, 14.429, 14.429, 20.643, 20.643, 20.643, 
20.643, 20.643, 20.643, 20.643, 20.643, 20.643, 20.643, 20.643, 
20.643, 20.643, 20.643, 20.643, 26.857, 26.857, 26.857, 26.857, 
26.857, 26.857, 26.857, 26.857, 26.857, 26.857, 26.857, 26.857, 
26.857, 26.857, 26.857, 33.071, 33.071, 33.071, 33.071, 33.071, 
33.071, 33.071, 33.071, 33.071, 33.071, 33.071, 33.071, 33.071, 
33.071, 33.071, 39.286, 39.286, 39.286, 39.286, 39.286, 39.286, 
39.286, 39.286, 39.286, 39.286, 39.286, 39.286, 39.286, 39.286, 
39.286, 45.5, 45.5, 45.5, 45.5, 45.5, 45.5, 45.5, 45.5, 45.5, 
45.5, 45.5, 45.5, 45.5, 45.5, 45.5, 51.714, 51.714, 51.714, 51.714, 
51.714, 51.714, 51.714, 51.714, 51.714, 51.714, 51.714, 51.714, 
51.714, 51.714, 51.714, 57.929, 57.929, 57.929, 57.929, 57.929, 
57.929, 57.929, 57.929, 57.929, 57.929, 57.929, 57.929, 57.929, 
57.929, 57.929, 64.143, 64.143, 64.143, 64.143, 64.143, 64.143, 
64.143, 64.143, 64.143, 64.143, 64.143, 64.143, 64.143, 64.143, 
64.143, 70.357, 70.357, 70.357, 70.357, 70.357, 70.357, 70.357, 
70.357, 70.357, 70.357, 70.357, 70.357, 70.357, 70.357, 70.357, 
76.571, 76.571, 76.571, 76.571, 76.571, 76.571, 76.571, 76.571, 
76.571, 76.571, 76.571, 76.571, 76.571, 76.571, 76.571, 82.786, 
82.786, 82.786, 82.786, 82.786, 82.786, 82.786, 82.786, 82.786, 
82.786, 82.786, 82.786, 82.786, 82.786, 82.786, 89, 89, 89, 89, 
89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89), y0 = c(0.1, 7.222, 
14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 
71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 
28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 
85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 
42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 
99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 
57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 
14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 
71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 
28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 
85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 
42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 
99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 
57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 
14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 
71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 
28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 
85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 
42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 
99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 
57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 
14.344, 21.466, 28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 
71.321, 78.444, 85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 
28.588, 35.711, 42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 
85.566, 92.688, 99.81, 0.1, 7.222, 14.344, 21.466, 28.588, 35.711, 
42.833, 49.955, 57.077, 64.199, 71.321, 78.444, 85.566, 92.688, 
99.81), resp = c(12.011, 11.551, 11.827, 11.888, 11.622, 11.181, 
11.249, 11.255, 10.933, 10.572, 10.362, 10.282, 10.3, 10.382, 
10.497, 12.111, 11.403, 11.694, 11.706, 11.488, 11.078, 11.018, 
10.996, 10.728, 10.426, 10.244, 10.164, 10.162, 10.211, 10.285, 
12.214, 11.341, 11.615, 11.545, 11.366, 10.974, 10.801, 10.75, 
10.525, 10.273, 10.114, 10.034, 10.014, 10.033, 10.072, 12.339, 
11.371, 11.605, 11.425, 11.264, 10.882, 10.61, 10.532, 10.338, 
10.123, 9.979, 9.896, 9.858, 9.85, 9.858, 12.516, 11.418, 11.628, 
11.354, 11.188, 10.829, 10.458, 10.36, 10.19, 9.999, 9.862, 9.769, 
9.71, 9.674, 9.649, 12.722, 11.487, 11.654, 11.325, 11.153, 10.804, 
10.356, 10.236, 10.088, 9.923, 9.788, 9.679, 9.591, 9.516, 9.447, 
12.936, 11.589, 11.671, 11.33, 11.167, 10.79, 10.309, 10.151, 
10.027, 9.895, 9.765, 9.636, 9.508, 9.382, 9.255, 13.171, 11.699, 
11.7, 11.372, 11.209, 10.787, 10.306, 10.094, 9.991, 9.897, 9.772, 
9.62, 9.449, 9.264, 9.072, 13.419, 11.789, 11.752, 11.457, 11.276, 
10.812, 10.329, 10.063, 9.973, 9.909, 9.784, 9.608, 9.392, 9.151, 
8.897, 13.663, 11.859, 11.824, 11.576, 11.375, 10.881, 10.364, 
10.055, 9.971, 9.921, 9.789, 9.586, 9.329, 9.037, 8.727, 13.897, 
11.956, 11.889, 11.691, 11.517, 10.983, 10.41, 10.064, 9.984, 
9.942, 9.797, 9.565, 9.267, 8.925, 8.561, 14.129, 12.111, 11.933, 
11.795, 11.7, 11.101, 10.464, 10.085, 10.012, 9.978, 9.821, 9.558, 
9.216, 8.82, 8.399, 14.374, 12.335, 11.955, 11.896, 11.907, 11.218, 
10.522, 10.116, 10.054, 10.032, 9.862, 9.567, 9.177, 8.724, 8.239, 
14.628, 12.606, 11.968, 12.002, 12.126, 11.331, 10.582, 10.156, 
10.104, 10.09, 9.906, 9.577, 9.139, 8.628, 8.081, 14.887, 12.899, 
11.978, 12.113, 12.348, 11.441, 10.642, 10.201, 10.157, 10.146, 
9.945, 9.582, 9.097, 8.53, 7.923)), row.names = c(NA, -225L), class = "data.frame")
denis
  • 199
  • 1
  • 8
  • Does it help if you use `geom_tile()` instead of `geom_raster()`? Rasters can only have regularly spaced cells, so the y-axis transformation seems to throw it off. – teunbrand Mar 09 '23 at 08:00
  • Unfortunately not, geom_tile() leads to the same problem. – denis Mar 09 '23 at 08:11
  • @teunbrand, it seems that adjusting height in geom_tile could be a solution, but how to create a function that would allow to adjust heights of bands according to the YJ transformation (or another transformation)? It's a big challenge! https://stackoverflow.com/questions/40090516/geom-tile-finding-the-proper-height-of-tiles – denis Mar 09 '23 at 12:54

1 Answers1

1

Below, a simple approach based on the excellent masher'answer, using the following packages:

library(bestNormalize)
library(akima)
library(dplyr)
library(ggplot2)
library(metR)
library(geomtextpath)
library(ggfx)

Yeo-Johnson transformation of y-axis scale (ok):

# Yeo-Johnson's Transformation    https://petersonr.github.io/bestNormalize/articles/bestNormalize.html
yeoj_y0 <- yeojohnson(dat$y0, standardize = FALSE)

# interpolate on Yeo-Johnson-transformed y-axis scale
dat2 <-interp2xyz(
  interp(x = dat$x0, y = yeoj_y0[["x.t"]], z = dat$resp,
         duplicate="mean", nx = 200, ny = 200), data.frame = TRUE)

# contour plot with full color gradient
y_breaks <- predict(yeoj_y0, newdata = c(0.1,10,20,30,40,50,60,70,80,90,100,110))
dat2 %>%
  ggplot(aes(x = x, y = y, z = z, fill = z)) + 
  geom_tile() + 
  scale_x_continuous(breaks = c(0,15,30,45,60,75,90), labels=c(0,15,30,45,60,75,90)) +
  scale_y_continuous(breaks = y_breaks, labels=c(0.1,10,20,30,40,50,60,70,80,90,100,110)) +
  with_outer_glow(geom_textcontour(aes(z = z), linetype = NA), colour = 'white', expand = 3, sigma = 1) +
  geom_textcontour(aes(z = z), textcolour = NA) +
  scale_fill_gradientn(
    colours = c("red2", "white", "blue2"),
    values = scales::rescale(c(min(dat$resp), intercept, max(dat$resp))),
    limits = c(7, 15),
    guide=guide_colourbar(reverse = TRUE)) +
  labs(fill = "resp") +
  ylab("y0  (Yeo-Johnson transformation)") + xlab("x0")

enter image description here

Examples of other transformation:

Log10 transformation of y-axis scale:

# log transformation    https://petersonr.github.io/bestNormalize/articles/bestNormalize.html
log_y0 <- log_x(dat$y0, standardize = FALSE)

# interpolate transformation on y-axis scale
dat2 <-interp2xyz(
  interp(x = dat$x0, y = log_y0[["x.t"]], z = dat$resp,
         duplicate="mean", nx = 200, ny = 200), data.frame = TRUE)

# contour plot with full color gradient
y_breaks <- predict(log_y0, newdata = c(0.1,10,20,30,40,50,60,70,80,90,100,110))
dat2 %>%
  ggplot(aes(x = x, y = y, z = z, fill = z)) + 
  geom_tile() + 
  scale_x_continuous(breaks = c(0,15,30,45,60,75,90), labels=c(0,15,30,45,60,75,90)) +
  scale_y_continuous(breaks = y_breaks, labels=c(0.1,10,20,30,40,50,60,70,80,90,100,110)) +
  with_outer_glow(geom_textcontour(aes(z = z), linetype = NA), colour = 'white', expand = 3, sigma = 1) +
  geom_textcontour(aes(z = z), textcolour = NA) +
  scale_fill_gradientn(
    colours = c("red2", "white", "blue2"),
    values = scales::rescale(c(min(dat$resp), intercept, max(dat$resp))),
    limits = c(7, 15),
    guide=guide_colourbar(reverse = TRUE)) +
  labs(fill = "resp") +
  ylab("y0  (Log10 transformation)") + xlab("x0")

enter image description here

Power ^0.25 transformation of y-axis scale:

# power transformation
power_y0 <- dat$y^0.25

# interpolate transformation on y-axis scale
dat2 <-interp2xyz(
  interp(x = dat$x0, y = power_y0, z = dat$resp,
         duplicate="mean", nx = 200, ny = 200), data.frame = TRUE)

# contour plot with full color gradient
y_breaks <- c(0.1,10,20,30,40,50,60,70,80,90,100,110)^0.25
dat2 %>%
  ggplot(aes(x = x, y = y, z = z, fill = z)) + 
  geom_tile() + 
  scale_x_continuous(breaks = c(0,15,30,45,60,75,90), labels=c(0,15,30,45,60,75,90)) +
  scale_y_continuous(breaks = y_breaks, labels=c(0.1,10,20,30,40,50,60,70,80,90,100,110)) +
  with_outer_glow(geom_textcontour(aes(z = z), linetype = NA), colour = 'white', expand = 3, sigma = 1) +
  geom_textcontour(aes(z = z), textcolour = NA) +
  scale_fill_gradientn(
    colours = c("red2", "white", "blue2"),
    values = scales::rescale(c(min(dat$resp), intercept, max(dat$resp))),
    limits = c(7, 15),
    guide=guide_colourbar(reverse = TRUE)) +
  labs(fill = "resp") +
  ylab("y0  (Power ^0.25 transformation)") + xlab("x0")

enter image description here

denis
  • 199
  • 1
  • 8