Search code examples
pythonrplotgnuplot

Library/tool for drawing ternary/triangle plots


I need to draw ternary/triangle plots representing mole fractions (x, y, z) of various substances/mixtures (x + y + z = 1). Each plot represents iso-valued substances, e.g. substances which have the same melting point. The plots need to be drawn on the same triangle with different colors/symbols and it would be nice if I could also connect the dots.

I have looked at matplotlib, R and gnuplot, but they don't seem to be able to draw this kind of plot. The 3rd party ade4 package for R seems to be able to draw it, but I'm not sure if I can draw multiple plots on the same triangle.

I need something that runs under Linux or Windows. I'm open to any suggestions, including libraries for other languages, e.g. Perl, PHP, Ruby, C# and Java.


Solution

  • R has an external package called VCD which should do what you want.

    The documentation is very good (122 page manual distributed w/ the package); there's also a book by the same name, Visual Display of Quantitative Information, by the package's author (Prof. Michael Friendly).

    To create ternary plots using vcd, just call ternaryplot() and pass in an m x 3 matrix, i.e., a matrix with three columns.

    The method signature is very simple; only a single parameter (the m x 3 data matrix) is required; and all of the keyword parameters relate to the plot's aesthetics, except for scale, which when set to 1, normalizes the data column-wise.

    To plot data points on the ternary plot, the coordinates for a given point are calculated as the gravity center of mass points in which each feature value comprising the data matrix is a separate weight, hence the coordinates of a point V(a, b, c) are

    V(b, c/2, c * (3^.5)/2
    

    To generate the diagram below, i just created some fake data to represent four different chemical mixtures, each comprised of varying fractions of three substances (x, y, z). I scaled the input (so x + y + z = 1) but the function will do it for you if you pass in a value for its 'scale' parameter (in fact, the default is 1, which i believe is what your question requires). I used different colors & symbols to represent the four data points, but you can also just use a single color/symbol and label each point (via the 'id' argument).