# Version 2.2.2 Released

ggtern version 2.2.2 has just been submitted to CRAN, and it includes a number of new features. This time around, I have adapted the hexbin geometry (and stat), and additionally, created an almost equivalent geometry which operates on a triangular mesh rather than a hexagonal mesh. There are some subtle differences which give some added functionality, and together these will provide an additional level of richness to ternary diagrams produced with ggtern, when the data-set is perhaps significantly large and points themselves start to lose their meaning from visual clutter.

### Ternary Hexbin

Firstly, lets look a the ternary hexbin, which, as the name suggests has the capability to bin points in a regular hexagonal grid to produce a pseudo-surface. Now in the original ggplot version, this geometry is somewhat limiting since it only performs a ‘count’ on the number of points in each bin, however, it is not hard to imagine how performing a ‘mean’ or ‘standard deviation’, or other user-defined scalar function on a mapping provided by the user:

1 2 3 4 5 6 7 8 9 |
set.seed(1) n = 5000 df = data.frame(x = runif(n), y = runif(n), z = runif(n), value = runif(n)) ggtern(df,aes(x,y,z)) + geom_hex_tern(bins=5,aes(value=value,fill=..count..)) |

Now because we can define user functions, we can do something a little more fancy. Here we will calculate the mean within each hexagon, and, also superimpose a text label over the top.

1 2 3 4 5 6 7 |
ggtern(df,aes(x,y,z)) + theme_bw() + geom_hex_tern(bins=5,fun=mean,aes(value=value,fill=..stat..)) + stat_hex_tern(bins=5,fun=mean, geom='text', aes(value=value,label=sprintf("%.2f",..stat..)), size=3, color='white') |

### Ternary Tribin

The ternary tribin operates much the same, except that the binwidth no longer has meaning, instead, the density (number of panels) of the triangular mesh is controlled exclusively by the ‘bins’ argument. Using the same data above, lets create some equivalent plots:

1 2 |
ggtern(df,aes(x,y,z)) + geom_tri_tern(bins=5,aes(value=value,fill=..count..)) |

There is a subtle difference with the labelling in the stat_tri_tern usage below, we have introduced a ‘centroid’ parameter, and this is because the orientation of each polygon is not consistent (some point up, some point down) and so unlike the hexbin where the centroid is returned by default, with the construction of the polygons being handled by the geometry, for the tribin, this is all handled in the stat.

1 2 3 4 5 6 7 |
ggtern(df,aes(x,y,z)) + theme_bw() + geom_tri_tern(bins=5,fun=mean,aes(value=value,fill=..stat..)) + stat_tri_tern(bins=5,fun=mean, geom='text', aes(value=value,label=sprintf("%.2f",..stat..)), size=3, color='white',centroid=TRUE) |

These new geometries have been on the cards for quite some time, several users have requested them. Many thanks Laurie and Steve from QEDInsight for partially supporting the development of this work, and forcing me to pull my finger out and get it done. Hopefully we will see these in some awesome publications this year at some time. Until this is accepted on CRAN, you will have to download from my bitbucket repo.

Cheers.

Hamo

Awesome work Nick!

Very cool man!

Fyi, if your blog links to r-bloggers it’s always nice to include in the first section, “btw this package does ____” so that newcomers know what it’s for

Do you know when CRAN might include the update for download for us plebs? I’m very excited to try this out. All I’m still getting is the 2.2.1 version.

Reuben, I am very sorry about this. There was a reverse dependency issue when submitting. CRAN admins have given the author of the offending package a grace period to attend to the problems with their package. If they have not responded within a few days more, the package will be released. Not my fault I am afraid.

Anyway, you can download and install from bitbucket repo by cloning locally, or alternatively using devtools:

devtools::install_git(‘https://bitbucket.org/nicholasehamilton/ggtern’)

Nicholas –

I have exactly the same problem w/ggtern

as this user had in August 2017,

– issue see:

https://bitbucket.org/nicholasehamilton/ggtern/issues/2/ggplot2-2219000

(ggtern conflict with the latest version of ggplot2 v. 2.2.1.9000).

Have you been to fix this compatibility

with ggplot2 v. 2.2.1.9000?

ii.e.: Does ggtern now work ok with ggplot2 v. 2.2.1.9000 ?.

Thank you for your any answer, Nicholas…

No I am sorry, compatibility with 2.2.1.9000 is not resolved yet.

Hi

I downloaded and installed ggtern using devtools::install_git(‘https://bitbucket.org/nicholasehamilton/ggtern’). I tried the following codes, but got an error as below:

> ggtern(df,aes(x,y,z)) + geom_hex_tern(bins=5,aes(value=value,fill=..stat..))

Error in f(…, self = self) : unused argument (plot$coordinates)

I used R 3.5.1, win64x. Any suggestions to solve that error? Thanks in advance!

Hi Nicolas, I have encountered the same problem as John, above. Any ideas on how to fix it? Thank you in advance!

Hi Nicolas, I have encountered the same problem as John, above. Any ideas on how to fix it? Thanks in advance!

Hi Nicolas,

I love this package and up until last week it was working great, but now I am getting an error even when attempting the examples found here. “Error in f(…, self = self) : unused argument (plot$coordinates)”. Any ideas? Like I said it is happening with your example data so I don’t thing it is something I am doing. Happened when I updated to the latest version of R.

Hi Nicholas,

First of all, thank you very much for all your hard work in making this great package available!

I’ve been doing some high-throughput work where I have an equally spaced grid of points in ternary space and have determined various thermodynamic properties for each of these, and have used geom_hex_tern to make nice surface-type plots of these. The trick here seems to be to set the binwidth to be smaller than the spacing of your points (since I’m simply wanting to plot discrete values rather than doing any binning).

However, I’m also interested in plotting factor (categorical) data, such as which phases are stable, or whether compositions are suitable or not for a given application. It was a bit tricky to figure out how to do this so I just thought I’d share the solution I found in case it’s useful to others.

1. First we set up a function to classify our points, such as this:

blah <- function(x){

if (x<0){

pt_class <- “Bad”

}else if (x==0){

pt_class <- “Marginal”

}else{

pt_class <- “Good”

}

return(pt_class)

}

2. Then in the plot, we can use this:

p <-ggtern(data=mydata, aes(x = x_Fe, y = x_Cr, z = x_Ni)) +

geom_hex_tern(binwidth=0.0001, fun=blah, aes(value=my_datacolumn),colour=”black”) +

theme_legend_position(“topright”) +

labs(fill=”Point class”)

print(p)

(Here

my_datacolumnis some column in the datasetmydatathat contains a vector of numerical values that we wish to use for the classification using the functionblah.)3. Then we can also modify the colours using some alternative discrete fill function such as scale_fill_viridis_d(), and reorder the legend items (default is alphabetic, which doesn’t make much sense here since we have a clear ranking system), thus:

p + scale_fill_viridis_d(limits= c(“Bad”,”Marginal”, “Good”))

Hope this is useful to someone!