# How to plot a barycentric line

I want to plot a barycentric function on an equilateral triangle (ternary plot). For example

f1 = {Abs[Sin[x]], Mod[x, 2], Abs[Cos[x]]};


At the moment I evaluate a list of data points and join them with a line

Show[{b3["PlotAxis"],ListPlot[b3["Data"][Range[0,100,1/#],f1],Joined->True]}]&/@{1,10,100} Where b3 is:

b3 = GetBarycentric;
b3["Axis"] = {{1/2, Sqrt/2}, {1, 0}, {0, 0}};
b3["Convert"][{a_, b_, c_}, axis_: b3["Axis"]] := Module[{
abc = {a, b, c}, sum = Total[{a, b, c}]},
Piecewise[{{ (axis[] a + axis[] b)/sum, sum > 0}, {axis[], sum <= 0}}]];
b3["Data"][values_, rlines_] := b3["Convert"][#] & /@ Transpose[rlines /. x -> values]
b3["PlotAxis"] := Graphics[{Thin, Line[{#1, #2, #3, #1}]}] & @@ b3["Axis"];


I can not use listplots 'Joined->True', because lines are intermittent. How can I transform the function and plot it?

A ternary plot is a plot on the nonnegative unit simplex in $\mathbb{R}^3$, so apply an affine change of basis (and rescale f1 to be sure its values lie on the simplex):

ClearAll[f1];
f1[x_] := {Abs[Sin[x]], Mod[x, 2], Abs[Cos[x]]};

With[{xyToTernary = {{0, 1, 1/2}, {0, 0, Sqrt/2}}},
ParametricPlot[xyToTernary . (f1[x] / Total[f1[x]]), {x, 1, 3^5},
AxesOrigin -> {0, 0}, PlotRange -> {0, 1},
Prolog -> {White, EdgeForm[Black], Polygon[{{0, 0}, {1, 0}, {1/2, Sqrt/2}}]}]
] Due to the nature of your function, it would be a good idea to break it at integral values of x by including the option Exclusions -> Range[3^5]: If you would like to visualize the 3D to 2D relationship inherent in these plots, you can ask Mathematica to do the projecting for you (but the 2D quality is degraded):

Show[
Graphics3D[{White, EdgeForm[Black], Polygon[{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}]},
ViewVector -> {1, 1, 1}, ViewPoint -> {-8, -8, -8},
ViewVertical -> {0, 0, 1}, ViewCenter -> {1/3, 1/3, 1/3},
ViewAngle -> \[Pi]/2,  Lighting -> {{"Ambient", White}}],
ParametricPlot3D[f1[x] / Total[f1[x]], {x, 1, 3^5},
Exclusions -> Range[3^5]], Axes -> {True, True, True}
]


(Image not shown.)

• Probably cleaner to use Normalize[f1[x], Total]. May 6, 2013 at 12:15

You can use Exclusions to exclude points where your function is discontinuous. For example

Plot[Evaluate[f1/Total[f1]], {x, 0, 10}, Exclusions -> Range[0, 10, 2]] and

triangle = {{0, 0}, {1, 0}, {1/2, Sqrt/2}};

ParametricPlot[f1.triangle/Total[f1], {x, 0, 200},
Epilog -> {EdgeForm[Red], FaceForm[], Polygon[triangle]},
PlotRange -> {{0, 1}, {0, 1}}, PlotRangePadding -> .1, Axes -> False,
Exclusions -> Range[0, 200, 2]] Edit

As whuber pointed out in the comment below, the plot looks a bit ragged near the bottom and right edge. You can correct this by increasing the number of plot points and the maximum number of recursions, e.g.

ParametricPlot[f1.triangle/Total[f1], {x, 0, 200},
Epilog -> {EdgeForm[Red], FaceForm[], Polygon[triangle]},
PlotRange -> {{0, 1}, {0, 1}}, PlotRangePadding -> .04,
Axes -> False, PlotPoints -> 200,
MaxRecursion -> 10,
Exclusions -> Range[0, 200, 2]]

• I was editing my post to point out the advantage of Exclusions when this reply appeared. :-) Notice that with this function you need to exclude all integers, not just the even ones. (Look at the detail along the upper right and bottom edges.) Apr 20, 2012 at 20:49
• @whuber I was just trying to fix that :-) The function isn't actually discontinuous there -- just the derivative. You can correct it by cranking up the number of PlotPoints and MaxRecursion. Apr 20, 2012 at 20:52
• Yep...but I suspect it's more efficient just to declare the cusps explicitly (when you know them, as in this case) rather than asking for a finer mesh. Apr 20, 2012 at 20:56
• @whuber hmm, you got a point there Apr 20, 2012 at 20:58