# Ternary plots in GMT.jl

**URL:** <https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181>\
**Category:** Visualization\
**Tags:** plotting, gmt\
**Created:** [June 19, 2021, 12:45pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181 "2021-06-19T12:45:12Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [June 19, 2021, 12:45pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/1 "2021-06-19T12:45:12Z")

</div>

The ternary plots topic has been raised here several times. I’ve added ternary plots to GMT.jl. Unfortunately it’s still not yet possible to slant the ticks, which helps a lot in reading the graphs, as that it will have to wait until GMT itself can do it.

Several examples are shown [here](https://www.generic-mapping-tools.org/GMT.jl/dev/gallery/ternary/ternary/) and a quick example can be obtained with:

```julia
ternary("@ternary.txt", labels=("Clay","Silt","Sand"), image=true, marker=:p, show=true)

```

 ![GMTjl_tmp](https://global.discourse-cdn.com/julialang/original/3X/1/e/1e697500c2fcf80d61ab0c752c9bd92f1e89dbca.png)

---

<div class="post-metadata">

**Author:** ![EvoArt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evoart/32/25357_2.png) [@EvoArt](https://discourse.julialang.org/u/EvoArt)\
**Post date:** [June 20, 2021, 6:17am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/2 "2021-06-20T06:17:14Z")

</div>

These look great! Thanks

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [July 4, 2021, 3:22am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/3 "2021-07-04T03:22:18Z")

</div>

Can GMT.jl produce a ternary plot with lines by (smoothly) connecting given points? Note it is neither scatter plot nor contour plot, such as the plot below:

 ![ternary](https://global.discourse-cdn.com/julialang/original/3X/8/0/80a1b284a9866ef4eb6b525cb5f73bf1e29f8430.jpeg)

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 4, 2021, 6:00pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/4 "2021-07-04T18:00:17Z")

</div>

Interested also on how to do this with GMT.

Fyi, it is already possible to do something like it using [TernaryPlots.jl](https://github.com/jacobusmmsmit/TernaryPlots.jl), a package that seems to be at early stages:

 ![TernaryPlots_smooth_curves](https://global.discourse-cdn.com/julialang/original/3X/4/7/47c288d0900fbf08d5e8896f7624211784d1a877.png)

The corresponding code is provided below:

```julia
using TernaryPlots

b = 0:0.01:0.3
c1 = (1 .- b).^3 .- 0.7^3
c2 = (1 .- 2*b).^2 .- 0.4^2
t1 = tern2cart.(1 .- b .- c1, b, c1)
t2 = tern2cart.(1 .- b .- c2, b, c2)

p = TernaryPlots.ternary_plot(title="TernaryPlots.jl",labels=(A="A", B="B", C="C"))
plot!(p, [t1...], lw=2, lc=:red)
plot!(p, [t2...], lw=2, lc=:blue)

```

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [July 4, 2021, 10:29pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/5 "2021-07-04T22:29:31Z")

</div>

OK, normally the ternary module in GMT (the C package) does not allow plotting lines. But symbols in GMT can be lots of things, including entities called decorated lines (see this [example](https://www.generic-mapping-tools.org/GMT.jl/dev/gallery/scripts_agu/decorated_I/)) and we can make use of them to plot lines.

You can now plot lines using this trick, but because it’s a trick the hard core GMT syntax must be used. Another problem I found is that apparently `ternary` in GMT.jl requires input data via a file. So please open an issue in GMT.jl requesting a proper friendly syntax to do this task. So far you’ll have to do this.

Save data in a text file (for example put this matrix [0.1 0.4 0.5; 0.2 0.0 0.8] in a file called “tern.dat”, one row per line) and use it as

```julia
ternary("tern.dat", S="~n1:+sc0.01", par=(MAP_DEFAULT_PEN="1,red",), show=true)

```

- The **S=…** is the trick to make a _decorated_ line but one with an invisible small circle
- the `par=(MAP_DEFAULT_PEN="1,red",)` tells it to plot a red line of 1p thickness. Omitting this option plots a 0.25p black line (the GMT default)

 ![GMTjl_tmp](https://global.discourse-cdn.com/julialang/original/3X/3/a/3a9ab0fba8e46f00035631f65c08d35168f02d5b.png)

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [July 5, 2021, 12:51am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/6 "2021-07-05T00:51:48Z")

</div>

Thanks! I find the API of TernaryPlots.jl is more pleasing and the look is great.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [July 5, 2021, 1:09am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/7 "2021-07-05T01:09:10Z")

</div>

> [@liuyxpp](#):
>
> I find the API of TernaryPlots.jl is more pleasing and the look is great.

Me too, and that’s why I said.

> [@joa-quim](#):
>
> So please open an issue in GMT.jl requesting a proper friendly syntax to do this task. So far you’ll have to do this.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [July 5, 2021, 6:01pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/8 "2021-07-05T18:01:01Z")

</div>

It turns out that a good improvement can be achieved with little changes, though I still need to find why it errors when one tries to add a Title.

With GMT.jl#master we can now expand a bit Rafael’s example

```julia
b = 0:0.01:0.3
c1 = (1 .- b).^3 .- 0.7^3
c2 = (1 .- 2*b).^2 .- 0.4^2
t1 = tern2cart([(1 .- b .- c1) b c1]) # Note that GMT.jl function expects a Mx3 matrix
t2 = tern2cart([(1 .- b .- c2) b c2])

ternary(labels=("A", "B", "C"))

plot!(t1, lw=2, lc=:red, ls="line& (a) &")	# line style -> fancy new stuff
plot!(t2, lw=2, lc=:blue)
text!(tern2cart([0.3 0.4 0.3]), text="Umbilicus", font=18, show=true)

```

 ![GMTjl_tmp](https://global.discourse-cdn.com/julialang/original/3X/3/a/3aae2d610ba6a8e7e01fdc2ae857e64dda49d2ca.png)

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [January 12, 2026, 5:22pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/9 "2026-01-12T17:22:48Z")

</div>

How do we set the colorbar label? This

```Julia
ternary(..., colorbar=true, show=true)

```

shows the plot and the colorbar, but I cannot find a way to set the `label`.

Also, I see here [How to make a slope map — GMT Examples documentation](https://www.generic-mapping-tools.org/gmt-examples/gallery/images/slope.html) that is possible to set that pointy highclip, is there an option for that in GMT.jl, including the lowclip?

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [January 13, 2026, 1:10am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/10 "2026-01-13T01:10:48Z")

</div>

OK, here’s how it works. The [colorbar](https://www.generic-mapping-tools.org/GMTjl_doc/documentation/modules/colorbar.html) is a separate command that allows all parameter setting. But for convenience it can be embedded in imaging command (`ternary` in this case). That can be done by setting it to true, which uses default settings but accepts also being parametrized. _i.e._, we can use it like

```julia-auto
ternary("@ternary.txt", labels=("Clay","Silt","Sand"), image=true, marker=:p, colorbar=frame=(xlabel="Label long", ylabel=:units), show=true)

```

or

make the plot with the two commands separately:

```julia-auto
ternary("@ternary.txt", labels=("Clay","Silt","Sand"), image=true, marker=:p, figsize=10)
colorbar!(pos=(paper=true, anchor=(11,0), size=(8,0.5), justify=:BL, vertical=true),
               frame=(annot=:auto, ticks=:auto, xlabel="Label long", ylabel=:units), show=true)

```

Note that in the second case we must make the `anchor` and `size` play along with the `figsize`.

 ![GMTjl_j](https://global.discourse-cdn.com/julialang/original/3X/a/e/ae7b9c103526f75c21ed7a08b393cec0d6bd9a2b.png)

Regarding the second question, sorry but I didn’t get it. Basically we can control everything in GMT plots. Are you referring to the color scale?

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [January 13, 2026, 6:03am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/11 "2026-01-13T06:03:04Z")

</div>

thanks a lot.

I mean the highclip(possibly set a color) and lowclip. Usually represented by a tip-triangle (up and down). See the ones in makie 😄 [Colorbar | Makie](https://docs.makie.org/stable/reference/blocks/colorbar#Colorbar_page) `highclip = :cyan, lowclip = :red` Those color are used for values beyond the specified `range`

Also, I’m not using a file, but a matrix with 4 columns, and for some reason the image/countour are not being picked-up, fourth columns is not being taken as color for those primitives, but it does work for points. Does the txt file comes with some column-names? or

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [January 13, 2026, 8:16pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/12 "2026-01-13T20:16:22Z")

</div>

You can plot those triangles but then we must currently use the two commands call (`ternary` & `colormap`). Note the `triangles=true`

```julia-auto
ternary("@ternary.txt", labels=("Clay","Silt","Sand"), image=true, marker=:p, figsize=10)
colorbar!(pos=(paper=true, anchor=(11,0), size=(8,0.5), justify=:BL, vertical=true, triangles=true),
               frame=(annot=:auto, ticks=:auto, xlabel="Label long", ylabel=:units), show=true)

```

 ![GMTjl_j](https://global.discourse-cdn.com/julialang/original/3X/d/3/d3218370004ec63a2d5f32c5c7ab55b2e1d3f122.png)

But why are the triangles black & white? Because the GMT colormaps have the notion of background and foreground colors and those by default are black and white. And yes, we can change that but it requires that we manually create the colormap for this data limits (by default that is done automatically under the hood). To make those colors correspond to lowest and highest we do:

```julia-auto
C = makecpt(range=(0,75), bg=true)

```

and now we do

```julia-auto
ternary("@ternary.txt", labels=("Clay","Silt","Sand"), image=true, marker=:p, figsize=10, cmap=C)
colorbar!(pos=(paper=true, anchor=(11,0), size=(8,0.5), justify=:BL, vertical=true, triangles=true),
               frame=(annot=:auto, ticks=:auto, xlabel="Label long", ylabel=:units), show=true)

```

 ![GMTjl_j](https://global.discourse-cdn.com/julialang/original/3X/a/8/a8be64b7ddf62abbe233b94e69dad87d8962395b.png)

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [January 13, 2026, 8:21pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/13 "2026-01-13T20:21:25Z")

</div>

> [@lazarusA](#):
>
> Also, I’m not using a file, but a matrix with 4 columns, and for some reason the image/countour are not being picked-up, fourth columns is not being taken as color for those primitives, but it does work for points. Does the txt file comes with some column-names?

Don’t know why that is happening. Note that file used in this example has also only 4 columns

```julia-auto
julia> gmtread("@ternary.txt")
BoundingBox: [0.0, 1.0, 0.0, 0.921, 0.0, 0.981, 1.041, 70.844]

1000×4 GMTdataset{Float64, 2}
 Row │ col.1 col.2 col.3 col.4
─────┼─────────────────────────────
   1 │ 0.16 0.331 0.509 9.344
   2 │ 0.22 0.625 0.158 39.156
   3 │ 0.09 0.18 0.732 2.621
   4 │ 0.66 0.258 0.078 12.062
...

```

and reading it first into a variable still works fine.

```julia-auto
ternary(gmtread("@ternary.txt").data, labels=("Clay","Silt","Sand"), image=true, marker=:p, show=true)

```

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [January 14, 2026, 8:52am UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/14 "2026-01-14T08:52:07Z")

</div>

thanks a million! this was really helpful ❤ !

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [January 14, 2026, 6:11pm UTC](https://discourse.julialang.org/t/ternary-plots-in-gmt-jl/63181/15 "2026-01-14T18:11:49Z")

</div>

With master version one can now do

```julia-auto
ternary("@ternary.txt", labels=("Clay","Silt","Sand"), image=true, marker=:p,
             colorbar=(xlabel="Label long", ylabel=:units, triangles=true), show=true)

```
