2

I am trying to create a ternary contour filled plot with the library ggtern. The code used is

a <- c(0.50, 0.625, 0.375, 0.25, 0.5625, 0.125, 0.25, 0.3125, 0.375, 0.4375, 0.1875, 0.3125, 0.375, 0.4375)
b <- c(0.25, 0.1875, 0.3125, 0.375, 0.25, 0.4375, 0.25, 0.375, 0.375, 0.4375, 0.875, 0.3125, 0.25, 0.125)
c <- c(0.25, 0.1875, 0.3125, 0.375, 0.1875, 0.4375, 0.50, 0.3125, 0.25, 0.125, 0.625, 0.375, 0.375, 0.4375) 
d <- c(77.82325, 74.59318767, 76.76495015, 76.62122282, 77.95608657, 76.91320817, 68.50986659,8.53724416,80.32237597, 85.43315399, 61.80292426, 74.71471485, 73.27176908, 67.51782848)
df <- data.frame(a, b, c, d)

df$id <- 1:nrow(df)

#Build Plot
ggtern(data = df,aes(x = c,y = a,z = b)) +
stat_density2d(geom = "polygon", n = 400, aes(fill = ..level.., weight = d, alpha = abs(..level..))) +
geom_density_tern(aes(weight = d,color = ..level..), n = 400) +
geom_point(aes(fill = d),color = "black",size = 5,shape = 21) +
geom_text(aes(label = id),size = 3) +
labs(x = "X (%)",y = "Y (%)",z = "Z (%)",title = "Title", size = 3) +
scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
scale_color_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
theme_custom(base_size = 12, base_family = "", col.T = "black", col.L = "black", col.R = "black", col.BG = "white") +
tern_anticlockwise() +
tern_limits(breaks = seq(0.1,1,by = 0.1)) + #AFFECT ALL SCALES
theme(axis.tern.arrowstart = 0.4,axis.tern.arrowfinish = 0.6) +
theme(legend.justification = c(0,1), legend.position = c(0,1)) +
guides(fill = guide_colorbar(order = 1), alpha = guide_legend(order = 2), color = "none") +
labs( title = "Ternary filled contour plot", fill = "Value, V",alpha = "|V - 0|")

But I get the following warning message:

Error: coord_tern requires the following missing aesthetics: z

Why does this error occur and how to fix it? Please help

Mike Wise
  • 22,131
  • 8
  • 81
  • 104
  • Welcome to SO. +1 for providing a dataset to demonstrate the problem. In future, please provide a *minimal* reproducible example. See [this post](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610#5963610) for how to do that. In essence this means stripping out all the code that's irrelevant to the problem. – jlhoward Sep 04 '15 at 07:18

2 Answers2

5

@jhoward, thanks for the explanation to the question.

I wanted to also demonstrate some additional functionality in the more recent versions of ggtern. Please see below the interpolation geometry, for surface modelling:

ggtern(data = df,aes(x = c,y = a, z = b)) + 
  geom_interpolate_tern(aes(value=d,colour=..level..),bins=50) +
  geom_point(aes(color=d),size=10) + 
  geom_text(aes(label=round(d,0)),size=3) + 
  theme_bw() + 
  theme(legend.position=c(0,1),
        legend.justification=c(0,1)) + 
  scale_colour_gradient(low='green',high='red') + 
  labs( title = "Ternary filled contour plot", colour = "Value, V")

Which produces the following output:

example contour

Nicholas Hamilton
  • 10,044
  • 6
  • 57
  • 88
  • hi @jlhoward ! . Thank you so much for your help . I need to fill z - level and gradient of contour lines according to d variable(from column d). I need a plot like previous one with d filled contour lines and gradient (which is not interpolation geometry). But this interpolation geometry plot is really impressive as well. Thanks – Nishan Maduranga Sep 10 '15 at 18:57
2

When something like this happens the obvious approach is to deconstruct your code to see where exactly the error is occurring. If you had done that, you'd know it is in call to stat_density2d(...). I was unable to make the ggtern version of stat_density2d(...) work at all (although I'd love to see an example where someone else does).

If you remove that call, and put the fill=..level.. aesthetic into geom_density_tern(...), you get this:

library(ggtern)
ggtern(data = df,aes(x = c,y = a, z = b)) +
  geom_density_tern(aes(fill=..level..),n = 400) +
  geom_point(aes(fill = d),color = "black",size = 5,shape = 21) +
  geom_text(aes(label = id),size = 3) +
  labs(x = "X (%)",y = "Y (%)",z = "Z (%)",title = "Title", size = 3) +
  scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
  scale_color_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
  theme_custom(base_size = 12, base_family = "", col.T = "black", col.L = "black", col.R = "black", col.BG = "white") +
  tern_anticlockwise() +
  tern_limits(breaks = seq(0.1,1,by = 0.1)) + #AFFECT ALL SCALES
  theme(axis.tern.arrowstart = 0.4,axis.tern.arrowfinish = 0.6) +
  theme(legend.justification = c(0,1), legend.position = c(0,1)) +
  guides(fill = guide_colorbar(order = 1), alpha = guide_legend(order = 2), color = "none") +
  labs( title = "Ternary filled contour plot", fill = "Value, V",alpha = "|V - 0|")

Notice how the contour fill is all yellow. This is happening because you are trying to use fill for two different things: the z-level (from column b), and the points, where fill comes from column d. ggplot (and gggtern by extension) creates a single fill scale. Since df$b is roughly in (0.1, 1) and df$d in roughly in the range (60,90), the contour fill levels are all at the low end of that range and are therefore yellow.

If you really want a different color palette for the contour fill and the points, you could use the color aesthetic for the points:

library(ggtern)
ggtern(data = df,aes(x = c,y = a, z = b)) +
  geom_density_tern(aes(fill=..level..),n = 400) +
  geom_point(aes(color = d),size = 8,shape = 20) +
  geom_text(aes(label = id),size = 3) +
  labs(x = "X (%)",y = "Y (%)",z = "Z (%)",title = "Title", size = 3) +
  scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
  scale_color_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
  theme_custom(base_size = 12, base_family = "", col.T = "black", col.L = "black", col.R = "black", col.BG = "white") +
  tern_anticlockwise() +
  tern_limits(breaks = seq(0.1,1,by = 0.1)) + #AFFECT ALL SCALES
  theme(axis.tern.arrowstart = 0.4,axis.tern.arrowfinish = 0.6) +
  theme(legend.justification = c(0,1), legend.position = c(0,1)) +
  guides(fill = guide_colorbar(order = 2), color = guide_colorbar(order = 1)) +
  labs( title = "Ternary filled contour plot", color = "Value, V", fill = "|V - 0|")

Edit: Add as per OP's comment.

ggtern(data = df,aes(x = c,y = a, z = b)) +
  geom_density_tern(aes(fill=..level..),n = 400) +
  geom_point(aes(color = d),size = 8,shape = 20) +
  geom_text(aes(label = id),size = 3) +
  labs(x = "X (%)",y = "Y (%)",z = "Z (%)",title = "Title", size = 3) +
  scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
  scale_color_gradient2(low = "green", mid = "yellow", high = "red", limits=c(60,90),midpoint = 75) +
  theme_custom(base_size = 12, base_family = "", col.T = "black", col.L = "black", col.R = "black", col.BG = "white") +
  tern_anticlockwise() +
  tern_limits(breaks = seq(0.1,1,by = 0.1)) + #AFFECT ALL SCALES
  theme(axis.tern.arrowstart = 0.4,axis.tern.arrowfinish = 0.6) +
  theme(legend.justification = c(0,1), legend.position = c(0,1)) +
  guides(fill = guide_colorbar(order = 2), color = guide_colorbar(order = 1)) +
  labs( title = "Ternary filled contour plot", color = "Value, V", fill = "|V - 0|")

jlhoward
  • 58,004
  • 7
  • 97
  • 140
  • Hi @jlhoward !, Thanks for the reply. I need to fill z - level and points from column d and I need to change the value range just 60 -90. Could you please help me to do this? your help will be really appreciated . – Nishan Maduranga Sep 07 '15 at 02:37
  • How is that different from the second image? (BTW: it looks like I just posted the same code twice - my mistake. It's been edited so that now the second snippet really does produce the second image.) To change the color values range, use `limits=c(60,90)` in the call to `scale_color_gradient2(...)`, and change the midpoint to, e.g. 75. – jlhoward Sep 07 '15 at 14:22
  • hi @jlhoward ! I need to fill z - level from column d and change the color range 60-90 as well . I changed the limits=c(60,90) in the call to scale_color_gradient2(...). But didn't work to me. Could you please post the code for me with these changes. your help will be really appreciated . – Nishan Maduranga Sep 07 '15 at 16:01
  • Added an example of setting color range to (60,90). Note that one of your rows has d < 60, so that point (id = 8) shows up as grey. – jlhoward Sep 08 '15 at 23:19
  • @jhoward, Thanks for explaining the above. I was forced to make the difficult decision to separate the ggtern density geom and stat from the ggplot2 original versions, because of some conflicts arising during the construction routine. As of version 1.0.6.0 (current version on CRAN), the functions are `geom_density_tern(...)` and `stat_density_tern(...)`. I hope to not make such drastic changes again in the future. Apologies to anyone if it has resulted in broken scripts written under the previous versions. – Nicholas Hamilton Sep 10 '15 at 01:33
  • hi @jlhoward ! I need to fill z - level and gradient of contour lines according to d variable(from column d). I need a plot like previous one with d filled contour lines and gradient (which is not interpolation geometry). But this interpolation geometry plot is really impressive as well. Thanks – Nishan Maduranga Sep 15 '15 at 03:10