File Exchange

image thumbnail


version (151 KB) by Carl Sandrock
Plots ternary phase data on a ternary phase diagram.


Updated 12 Aug 2017

GitHub view license on GitHub

Plot ternary diagrams in Matlab

Comments and Ratings (129)

Zheng Liang

Carl Sandrock

Marcellino: Thank you. If you mean is it possible to zoom in on a particular corner, not at the moment. You can kind of fake it by doing the labelling differently, but I haven't really found a simple way to implement it.

first of all excellent job. Just one question, is it possible to change the scale on the axis?

Jiaming Zhu

Carl Sandrock

Yes, ternlabel assumes clockwise labeling. A workaround could be to use vertexlabel instead and supply the names the other way around.

or i managed to do it by changing in the file Axes and Coords to counter-clockwise. now my only problem is that all the labes are super strangely shifted , i think there is a no "axes" adaptation if the system is counter-clockwise
can that be?

Carl Sandrock

Hi Michael. If you mean to label the vertices the other way around, there is a work-in-progress for this in the code of terncoords.m but it is not yet enabled as a user-available option. If you always want it the other way around you can change it there. I'd welcome a pull request to make this a user option all over the package.

Very nice , thanks a lot!
Quick question, how can i change the direction of axis? that it goes from 0 to 1 but the other way?

Chang Liu

Hi Alka. The package can be used to present coordinates on a single plane, which translates to three component mixtures which are defined by two compositions. When you talk about images (2d), one can easily obtain the triangular coordinates using terncoords and then just plot the images using "normal" 2d plotting commands like pcolor. If you want a more detailed reply, I recommend that you ask a question on Stack Overflow and use the "ternplot" tag, which I monitor.

Alka Singh

Hi Carl, The code is for plotting one dimension datasets. Can you please suggest how can we use it to plot 3 fractional images (2D) into a ternary plot. Looking forward to your reply.

Dear Dot, I am suggesting you use the following as a reference, thanks for acknowledging the codes:

Sandrock, C., Afshari, S., 2016. alchemyst/ternplot: DOI version [Data set]. Zenodo.

Carl Sandrock

I have registered a DOI for this project for people who would like to reference: The DOI is 10.5281/zenodo.166760

You can cite as Carl Sandrock; Shahab Afshari, "Plot ternary diagrams in Matlab", DOI 10.5281/zenodo.166760


Dot Dumuid

I have used this code to produce figures for a manuscript. How do I cite?

Great Code!

A note to people using the comments to ask questions: I do not receive notification of every new comment in this forum. I have created a ternplot label on stackoverflow, which I monitor ( If you are reporting a bug, it is better to do this on the github issue page for this project:

Is it possible to add label to data points on the graph? I have a phase diagram and would like to put notation to the solutions I use?

It is a great code! thank you!

Emilie M


I am sorry, I have another question. It seems that the colorbar does not match with the value of the surface (representing the percent of cells). For example, the values go from 22 to 84 % but the colorbar is set up to 38 to 58. I know that I can set up the colorbar with caxis([22, 84]) , but I am wondering: did I do something wrong by coding:

ternsurf(XA, XB, XC, f3);
c = colorbar();

Yours sincerely,

Emilie M

I am sorry, it worked now when I do plot3(x, y, Cells);
with cells: my row data.
Thank you very much for your help!
I appreciate it!
Have a nice day!

Carl Sandrock

Hello Emilie. ternplot is an equivalent to the plot command. You can easily plot 3d points using plot3 after creating the ternary axis with a ternsurf command as follows:

ternsurf(XA, XB, XC, f3);
[x, y] = terncoords(XA, XB, XC);
hold on;
plot3(x, y, f3);
hold off;

Emilie M

I have a question. Is there a way to plot, in addition to the surface, some data points in 3 D and not in 2D? And also to plot them in different colors according if they are below or above the surface ?

I successed to plot the surface:
ternsurf(XA,XB,XC,f3);ternlabel('Trifluoperazine', 'Gemcitabine', 'Paclitaxel');
c = colorbar();

but I cannot plot data points in 3 D, the data points were plotted on the base of the ternary plot in 2 D with the command below:
ternplot(XA, XB, XC,'marker', 'd','markerfacecolor','yellow','markersize',5); ternlabel('Trifluoperazine', 'Gemcitabine', 'Paclitaxel');

And I would like them in 3D, so I tried the commands below, but it does not work. Do you have an idea ?

%%%%%%%%% points above the surface %%%%%%%%%%


%%%%%%%%% points below the surface %%%%%%%%%%

% %
ternplot(Xabove, Yabove, Zabove, 'd','red'); ternlabel('TFP', 'GEM', 'PTX');
hold on
ternplot(Xbelow, Ybelow, Zbelow, 'd','green'); ternlabel('TFP', 'GEM', 'PTX');

Yours sincerely,

Carl Sandrock

@evert: The ternpcolor function is designed to interpolate between data points using cubic interpolation.

Evert Merkx

When attempting to test this function, it will interpolate values to numbers that do not exists in the base dataset.
For example:
figure; ternpcolor(rand(1,100), rand(1,100), rand(1,100), rand(1,100));

Will plot a figure with a surface of values higher than 1 and lower than 0.
Is this a bug or am I using this function wrongly?

Zhaoxin Li

Dries: Sorry about the late reply. As of this moment, there is no such option (you can of course comment out the part which does the tick labling in the code). Could you report this as an issue on github (

Is there a possibility to not show the tick labels? This would help me a lot. Thanks!

Hsin, I'm only a student so I don't know exactly but if you play around with the order of A B and C in your input you can get it to generate how you like. Just be mindful of your axis when generating.

Hsin, try to do


This helped me create a ternary phase diagram that looked more like what I am used to!


Hi Carl,

I have data like this:
A=[0.9990 0.9413 0.1664 0.0002 0.0000]
B=[0.0010 0.0585 0.6672 0.0585 0.0010]
C=[0.0000 0.0002 0.1664 0.9413 0.9990]
There are five data points (from let to right in each row above.

When i do this:
The resulting figure seems fine. The position of the five data points (dots) are correct. However, if I do this:
ternplot(A,B,C,'-'), the results is a bit weird.
Even though the position of the data points are correct, the lines are not correctly connected. The second data point is not connect with a line to the third data point, but connect with a line to the fifth data point.
Did i do something wrong here?


Carl Sandrock

Santiago, ternary diagrams like the ones ternplot produces are designed specifically for mixtures of three components, so the components _must_ add to 1 for the plots to make any kind of sense. For instance, what does it mean when all three your coordinates are zero? Is there nothing in your mixture?

Dear Carl,

I have some doubts about what to do when my data doesnt give one in the sumation, i mean:

these are the first rows of my data:

0 0 0 0.261652734
0 0 0.25 0.17307517
0 0 0.5 0.111067026
0 0 0.75 0.053096627
0 0 1 0.018623723

Cause y only move the C variable.

How can I solve it?

Halil Sozen

Dear Carl,

I have just accepted the answer. Also thanks a lot for the last question.


Carl Sandrock

Halil: Please accept the answer on Stack Overflow if you found it useful. Ternpcolor uses cubic interpolation by default.

Halil Sozen

Dear Carl,

Thanks a lot for the quick and useful response. I think I can take over the rest. My plot seems perfect now.

However, I want to ask a very last question. Can you please mention how the surface contour values changes in between two given point data ? İs that linear ?


Halil Sozen

Dear Carl,

Thanks for that useful code. I will use the outputs in my publication. Nevertheless, I need help from you to make some changes. I also asked several question on stack overflow. You can find the questions link in here:

I am looking forward to see your answers


Hello Carl , thank you very much for your spontaneous reply. Actually I made a mistake while sending the data. Now I have updated my data properly. Please check the data on stackover folw.

Hello Carl, I have updated my question on stack overflow. Can you please go through it.

Carl Sandrock

Sunil, I am chthonicdaemon on Stack Overflow. I have asked you a question there. You cannot expect me to solve your problem with so little information.

hello Carl, I have sent you the link obtained through stackoverflow for my question. Kindly do this favour.

Carl Sandrock

It will help to send me a link to the question.

Hello Carl Sandrock, I posted a question regarding my problem on stack overflow. Can you please solve my problem.

Carl Sandrock

Sunil, I am on Stack Overflow, so I recommend that you construct a question there giving the details of your situation.

Thank you very much for a great tool. I'm unable to make a ternary phase with my values. Plz can u assist me in achieving my goal. Presently working formulation of emusions.

Carl Sandrock

Sorry Gustav, there is no option for drawing partial triangular coordinates. I have created an issue for this on GitHub:

Thank you for a great tool. Is there any way to change the axis range? I am only able to get between 0 and 1 for all three axes. I am using version 2016a, is that a problem?

Scott Rowe

Carl, we would love to see a similar cool to creating tetrahedral plots (for quaternary systems). Any thoughts?

Carl Sandrock

The method you are using is correct, but remember that these x and y values will be in the rectangular coordinates that ternplot uses internally to plot the values. Unfortunately you will have to convert them back to fraction data yourself.


In ternplot, after having plotted the contour lines, is it possible to retrieve or extract the contour points along with the isocontour values?

I am trying to get it this way,

[cc, hh] = terncontour(SFCRec(:,1), SFCRec(:,2), SFCRec(:,3),SFCRec(:,i+3),v);
xPointsOfContour = get(hh(1), 'xdata'); % Get points along the first contour
yPointsOfContour = get(hh(1), 'ydata');
zPointsOfContour = get(hh(1), 'zdata');
hold on;

but I dont get the right points along the countour and their corresponding z values.

Carl Sandrock

It appears that the problem is related to the new graphics system object orientation ( I have made some changes that may cause it to work in the older version you are using. The original functions (all except ternplot_pro, which does histogramming and is newer) should work fine all the way back to 2006b.


Thanks Carl for answer. However, when I run tern_demo I get the same error.

Warning: Struct field assignment overwrites a value with class "double". See MATLAB R14SP2 Release Notes, Assigning Nonstructure
Variables As Structures Displays Warning, for details.
> In ternplot_pro at 75
In terndemo at 20
Reference to non-existent field 'Vertices'.

Error in ternplot_pro (line 76)
v = h.Vertices;

Error in terndemo (line 20)

Carl Sandrock

Have a look at terndemo.m, which shows how each of the functions can be used. If you just want to plot the data points you should use ternplot instead of ternplot_pro.


Can you please share data set used to generate these figures? I get an error, when I use three variables dataA, dataB, and dataC with N*1 form.
Warning: Struct field assignment overwrites a value with class "double". See MATLAB R14SP2 Release Notes, Assigning Nonstructure
Variables As Structures Displays Warning, for details.
> In ternplot_pro at 75
Reference to non-existent field 'Vertices'.

Error in ternplot_pro (line 76)
v = h.Vertices;

my usual variable set looks like:

dataA =



@James: there is unfortunately not currently a method to "zoom" on the simplex, so the vertices are always the pure components. I would welcome any attempts to change this.

Regarding the labels, I find it least ambiguous to use the vertexlabel routine to label the vertices.

@Carl: Thank you, I was able to straighten everything out. I do have another question. My graphs do not fill the entire triangle whereas the examples do. Am I missing something? My data is pretty concentrated so I am not sure if that is the reason why. Also, the chart titles do not seem to match with the proper axis. What axis goes to which label. Ex. I do a ternpcolor(A,B,C,D); then ternlabel('A label','B label' ,'C label;);
Is this correct?

@James: if you supply three arguments to ternpcolor instead of 4, it will use the third argument (C in your case) as the z-coordinate and recalculate the third composition as C=1 - (A+B). If you just want to plot positions, you should use ternplot. I see no reason why you should always see the same result with different inputs, though.

Can anyone help me out, I am trying to plot 3 vectors of values. However, whenever I do this I am getting the same graph.
I have my three vectors A B and C, size 1X625, I am using ternpcolor(A,B,C). No matter what my values are, I am getting the exact same chart. Is there something I am missing?

Carl Sandrock

@Michael I have fixed the problem with terndemo not working, and added a better way of handling options.

Unfortunately, as of the 20160405 modification, this is broken. ternplot has parameters A,B,C, majors, varargin, so it does not work as ternplot(A,B). Because of this, also terndemo is broken.

Carl Sandrock

@Neill I am more than happy to help, but I need more information. Try going to the GitHub page and registering an issue - this forum is not a great place for interactive debugging.

Neil Cheong

Hi @carl. If I'm working with a large data array with more than a hundred data like in @theak 's case, specifying the Z component may be complicated. Is there any function to 'auto-generate' such matrix according to my data size and value range?

jiang Han

Carl Sandrock

@theak, I don't understand how you would plot a 10k x 4 array on the ternary diagram. You would need three coordinates. I don't understand the data part of your arguments. Assuming your compositions were the first three columns of your data, perhaps you could try ternplot(data(:, 1), data(:, 2), data(:, 3))


Doesn't seem to work with my data. Sent a dataset of 10k x 4 points to this function and it just displays a blank plot. no error returned. tried running as A, B, data, as well as A, B, C, data. also tried normalizing A, B and C to 1. Nothing seemed to work.

Maybe the dataset was too big...

Unfortunately this is quite hard at the moment. If you're in a hurry, you can just edit line 62 of ternaxes.m to take out the *100. All the fractions are handled as 0-1 internally, it's just the labels that are shown as percentages.

thank you calr Sandrock,
May I know, can we change the scale to range of 0 to 1.0 insteatd of 0 to 100

Carl Sandrock

A good place to start is the terndemo.m file. You can run it to see output directly and perhaps modify it by removing the parts you don't need.

Hi, I new to MatLab. I need to draw ternary diagrams in MatLab.

I need guide how to use this file. Thx

Bikai Jin

Very easy to use

Carl Sandrock

Since barycentric coordinates don't really make sense outside the vertices, I didn't take negative values into account. You can try just finding the coordinates you're interested in using TERNCOORDS which should work fine with negatives and then using a normal plot statement from there. You can use TERNAXES to draw the axes.


This is a very handy tool. Is it possible to use it with negative values and without the normalization? I am having problems getting the axes to plot.

Carl Sandrock

Hi @kanes, you should be able to plot bultiple lines using "hold" and ternplot as in normal 2d plots. Perhaps you can post an issue with some sample code on the github repository for this project?


It is a great function, it is very helpful! Thank you very much!

I would like to know how to draw more than one graph on the same figure with a loop . because I tried to use 'for-loop', but there was no more scale and the boundary after plotting.

Reagard and thanks for your time!

Carl Sandrock

I have started a GitHub repository for this project - you can register feature requests there.

Thanks for the function. One problem I am experiencing is that the labeling produced by "vertexlabel" is not consistent with the placement by "ternplot". I presently use the following code to place the labels in the right spot:


Have others experienced this problem? Can it be corrected?

Great function, thanks for putting this up. It worked right away, without any tweaking, which is not always the case for files on FileExchange but is always much appreciated. One feature that I did not see right away is the ability to set the size and style of the tick mark labels and axis labels, i.e. change from size 10 to size 12, make bold, etc. I had to go and select each tick mark label individually to change its size. Other than that, super program.


Suggestions for improvements:
1) add an option to toggle whether to plot the grid lines or not.
2) terncontour allows passing additional comments to contour function

Qibiao Yu




Yuri K

Another suggestion. The vertex labels should be at 100%, not 0%.

Yuri K

Great function! -1 because labeling with gname cannot be used due to data sorting. Make the sort optional and/or return the sorting index.


Hi, this is really useful. :)) Anyhow, just to tell you that you can make this work on Octave (not very well, but decent enough to get things done), if in ternaxes.m you change
-cax = newplot;
+cax = gca();

It's really useful!

Many Thanks for this great tool! Only one question:
I want to have only a small part of the phase diagram because the solubilities in my experiments are small. How can I do this?

Scott Rowe

I agree with Marco, it would be useful if the program supported a 3d axis with scaling.




Hello, i need help with your ternplot routine. First of all, great tool for us chem. eng. students! Good work!
I want to know if its posible to add a label in the vertical axis in the 3d portion of the diagram. I need to add a temperature scale in the vertical axis.
Regards and thanks for your time!

Marco Scetta.


The perfect ternary plot tool...simple to use and easy to adapt to specific demands :) Thanks Carl!!!


Thanks a lot, it works really well. I would like to plot tie-lines as well. Do you have any idea how I can do that?


I need to make Piper trilinear diagrams using matlab. The ternary phase diagram is great, but it is only part of the Piper trilinear diagram (used to plot hydrogeochemical facies). Does anyone know how to create a Piper trilinear diagram in matlab?

I'm pretty sure that vertexlabel.m is not working quite correctly. If the data input using ternplot is
% b
% / \
% / \
% c --- a

% this function plots
% c
% / \
% / \
% a --- b

% and the vertex labelling needs to be input as vertexlabel(C,A,B)



When I used ternplot some of my points are off the grid (outside the triangle) and I haven't been able to figure out the cause. Has this happened to anyone else? Can anyone help me fix the problem?


Catherine Klapperich

Giuseppe Cardillo

Your work is excellent. Anyway there is a bug in ternplot.
Change line 33 in
function hpol = ternplot(A, B, C, varargin)
or, in alternative, change line 55 in
handles = q;

parvez alam

Wolfgang Mozart

I've been trying to use your solution for my data in excel file. I exported my data into matlab, but I got two errors:
??? Input argument "A" is undefined.

Error in ==> ternplot at 40
C = 1 - (A+B);

??? Input argument "A" is undefined.

Error in ==> ternlabel at 18
r(1) = text(0.35*sin(deg2rad(30)), 0.5, A, 'rotation', 60, 'horizontalalignment', 'center');
How can I solve this problem?

Wolfgang Mozart

Excellent work! Have you an Idea to get 3D ternary phase plot?

Marcela edith

soroush taghinejad

Karel Verscheure

Excellent work! Maybe someone can extend this to make advanced contourplots (liquidus surfaces in color etc.)?

Yash Mahendra

Thank you so much!! It's a boon for chem engg students!

John Dow

It's really cool!
it would be nice to have an option to draw more than one graph on the same figure. (hold on, hold off)

roxxot jang



thanks a lot

Priam Pillai

Excellent program. I used it for my lab reports works great.

joe salisbury


W Jirat

Very useful and amazing work.

Aanhanger...:) NOT!!!!!!!!!

Die massa toets was nie funny nie.
Ek is nie 'n student in jou klas nie, maar ek
het gehoor....

A. Schumann

These 2 routines do exactly what I've been looking for hours now. Thanks !


* Migrated to a GitHub repository
* Fixed the problem with vertexlabel using inconsistent labelling to the rest of the plotting routines.

Often requested features added -- terncontour and ternsurf for three-dimensional plots contributed by Peter Selkin. Plotting order (a, b, c) is now more standard. More modular design.

MATLAB Release Compatibility
Created with R2006b
Compatible with any release
Platform Compatibility
Windows macOS Linux

Discover Live Editor

Create scripts with code, output, and formatted text in a single executable document.

Learn About Live Editor