python-ternary

:small_red_triangle: Ternary plotting library for python with matplotlib

https://github.com/marcharper/python-ternary

Science Score: 51.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
    Links to: arxiv.org, biorxiv.org, zenodo.org
  • Committers with academic emails
    5 of 29 committers (17.2%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (12.0%) to scientific vocabulary

Keywords

python ternary-plots

Keywords from Contributors

game-theory computer-science mathematics evolutionary-game-theory prisoners-dilemma pde
Last synced: 6 months ago · JSON representation ·

Repository

:small_red_triangle: Ternary plotting library for python with matplotlib

Basic Info
  • Host: GitHub
  • Owner: marcharper
  • License: mit
  • Language: Python
  • Default Branch: master
  • Homepage:
  • Size: 15.4 MB
Statistics
  • Stars: 767
  • Watchers: 16
  • Forks: 156
  • Open Issues: 37
  • Releases: 8
Topics
python ternary-plots
Created over 13 years ago · Last pushed over 1 year ago
Metadata Files
Readme License Citation

README.md

python-ternary

DOI Join the chat at https://gitter.im/marcharper/python-ternary

This is a plotting library for use with matplotlib to make ternary plots plots in the two dimensional simplex projected onto a two dimensional plane.

The library provides functions for plotting projected lines, curves (trajectories), scatter plots, and heatmaps. There are several examples and a short tutorial below.

Gallery




Last image from: Genetic Drift and Selection in Many-Allele Range Expansions.

See the citations below for more example images.

Citations and Recent Usage in Publications

DOI

Have you used python-ternary in a publication? Open a PR or issue to include your citations or example plots!

See the partial list of citations and instructions on how to cite.

Installation

Anaconda

You can install python-ternary with conda:

bash conda config --add channels conda-forge conda install python-ternary

See here for more information.

Pip

You can install the current release (1.0.6) with pip: bash pip install python-ternary

With setup.py

Alternatively you can clone the repository and run setup.py in the usual manner:

bash git clone git@github.com:marcharper/python-ternary.git cd python-ternary python setup.py install

Usage, Examples, Plotting Functions

You can explore some of these examples with this Jupyter notebook.

The easiest way to use python-ternary is with the wrapper class TernaryAxesSubplot, which mimics Matplotlib's AxesSubplot. Start with:

python fig, tax = ternary.figure()

With a ternary axes object tax you can use many of the usual matplotlib axes object functions:

python tax.set_title("Scatter Plot", fontsize=20) tax.scatter(points, marker='s', color='red', label="Red Squares") tax.legend()

Most drawing functions can take standard matplotlib keyword arguments such as linestyle and linewidth. You can use LaTeX in titles and labels.

If you need to act directly on the underlying matplotlib axes, you can access them easily:

python ax = tax.get_axes()

You can also wrap an existing Matplotlib AxesSubplot object:

figure, ax = pyplot.subplots() tax = ternary.TernaryAxesSubplot(ax=ax)

This is useful if you want to use ternary as a part of another figure, such as

```python from matplotlib import pyplot, gridspec

pyplot.figure()
gs = gridspec.GridSpec(2, 2)
ax = pyplot.subplot(gs[0, 0])
figure, tax = ternary.figure(ax=ax)
...

```

Some ternary functions expect the simplex to be partitioned into some number of steps, determined by the scale parameter. A few functions will do this partitioning automatically for you, but when working with real data or simulation output, you may have partitioned already. If you are working with probability distributions, just use scale=1 (the default). Otherwise the scale parameter effectively controls the resolution of many plot types (e.g. heatmaps).

TernaryAxesSubplot objects keep track of the scale, axes, and other parameters, supplying them as needed to other functions.

Simplex Boundary and Gridlines

The following code draws a boundary for the simplex and gridlines.

```python import ternary

## Boundary and Gridlines
scale = 40
figure, tax = ternary.figure(scale=scale)

# Draw Boundary and Gridlines
tax.boundary(linewidth=2.0)
tax.gridlines(color="black", multiple=5)
tax.gridlines(color="blue", multiple=1, linewidth=0.5)

# Set Axis labels and Title
fontsize = 20
tax.set_title("Simplex Boundary and Gridlines", fontsize=fontsize)
tax.left_axis_label("Left label $\\alpha^2$", fontsize=fontsize)
tax.right_axis_label("Right label $\\beta^2$", fontsize=fontsize)
tax.bottom_axis_label("Bottom label $\\Gamma - \\Omega$", fontsize=fontsize)

# Set ticks
tax.ticks(axis='lbr', linewidth=1)

# Remove default Matplotlib Axes
tax.clear_matplotlib_ticks()

ternary.plt.show()

```

Drawing lines

You can draw individual lines between any two points with line and lines parallel to the axes with horizonal_line, left_parallel_line, and right_parallel_line:

```python import ternary

scale = 40
figure, tax = ternary.figure(scale=scale)

# Draw Boundary and Gridlines
tax.boundary(linewidth=2.0)
tax.gridlines(color="blue", multiple=5)

# Set Axis labels and Title
fontsize = 12
offset = 0.14
tax.set_title("Various Lines\n", fontsize=fontsize)
tax.right_corner_label("X", fontsize=fontsize)
tax.top_corner_label("Y", fontsize=fontsize)
tax.left_corner_label("Z", fontsize=fontsize)
tax.left_axis_label("Left label $\\alpha^2$", fontsize=fontsize, offset=offset)
tax.right_axis_label("Right label $\\beta^2$", fontsize=fontsize, offset=offset)
tax.bottom_axis_label("Bottom label $\\Gamma - \\Omega$", fontsize=fontsize, offset=offset)

# Draw lines parallel to the axes
tax.horizontal_line(16)
tax.left_parallel_line(10, linewidth=2., color='red', linestyle="--")
tax.right_parallel_line(20, linewidth=3., color='blue')

# Draw an arbitrary line, ternary will project the points for you
p1 = (22, 8, 10)
p2 = (2, 22, 16)
tax.line(p1, p2, linewidth=3., marker='s', color='green', linestyle=":")

tax.ticks(axis='lbr', multiple=5, linewidth=1, offset=0.025)
tax.get_axes().axis('off')
tax.clear_matplotlib_ticks()
tax.show()

```

The line drawing functions accept the matplotlib keyword arguments of Line2D.

Curves

Curves can be plotted by specifying the points of the curve, just like matplotlib's plot. Simply use:

ternary.plot(points)

Points is a list of tuples or numpy arrays, such as [(0.5, 0.25, 0.25), (1./3, 1./3, 1./3)],

```python import ternary

## Sample trajectory plot
figure, tax = ternary.figure(scale=1.0)
tax.boundary()
tax.gridlines(multiple=0.2, color="black")
tax.set_title("Plotting of sample trajectory data", fontsize=20)
points = []
# Load some data, tuples (x,y,z)
with open("sample_data/curve.txt") as handle:
    for line in handle:
        points.append(list(map(float, line.split(' '))))
# Plot the data
tax.plot(points, linewidth=2.0, label="Curve")
tax.ticks(axis='lbr', multiple=0.2, linewidth=1, tick_formats="%.1f")
tax.legend()
tax.show()

```

There are many more examples in this paper.

Scatter Plots

Similarly, ternary can make scatter plots:

```python import ternary

### Scatter Plot
scale = 40
figure, tax = ternary.figure(scale=scale)
tax.set_title("Scatter Plot", fontsize=20)
tax.boundary(linewidth=2.0)
tax.gridlines(multiple=5, color="blue")
# Plot a few different styles with a legend
points = random_points(30, scale=scale)
tax.scatter(points, marker='s', color='red', label="Red Squares")
points = random_points(30, scale=scale)
tax.scatter(points, marker='D', color='green', label="Green Diamonds")
tax.legend()
tax.ticks(axis='lbr', linewidth=1, multiple=5)

tax.show()

```

Heatmaps

Ternary can plot heatmaps in two ways and three styles. Given a function, ternary will evaluate the function at the specified number of steps (determined by the scale, expected to be an integer in this case). The simplex can be split up into triangles or hexagons and colored according to one of three styles:

  • Triangular -- triangular (default): coloring triangles by summing the values on the vertices
  • Dual-triangular -- dual-triangular: mapping (i,j,k) to the upright triangles △ and blending the neigboring triangles for the downward triangles ▽
  • Hexagonal -- hexagonal: which does not blend values at all, and divides the simplex up into hexagonal regions

The two triangular heatmap styles and the hexagonal heatmap style can be visualized as follows: left is triangular, right is dual triangular.



Thanks to chebee7i for the above images.

Let's define a function on the simplex for illustration, the Shannon entropy of a probability distribution:

python def shannon_entropy(p): """Computes the Shannon Entropy at a distribution in the simplex.""" s = 0. for i in range(len(p)): try: s += p[i] * math.log(p[i]) except ValueError: continue return -1.*s

We can get a heatmap of this function as follows:

```python import ternary scale = 60

figure, tax = ternary.figure(scale=scale)
tax.heatmapf(shannon_entropy, boundary=True, style="triangular")
tax.boundary(linewidth=2.0)
tax.set_title("Shannon Entropy Heatmap")

tax.show()

```

In this case the keyword argument boundary indicates whether you wish to evaluate points on the boundary of the partition (which is sometimes undesirable). Specify style="hexagonal" for hexagons. Large scalings can use a lot of RAM since the number of polygons rendered is O(n^2).

You may specify a matplotlib colormap (an instance or the colormap name) in the cmap argument.


Ternary can also make heatmaps from data. In this case you need to supply a dictionary mapping (i, j) or (i, j, k) for i + j + k = scale to a float as input for a heatmap. It is not necessary to include k in the dictionary keys since it can be determined from scale, i, and j. This reduces the memory requirements when the partition is very fine (significant when scale is in the hundreds).

Make the heatmap as follows:

python ternary.heatmap(data, scale, ax=None, cmap=None)

or on a TernaryAxesSubplot object:

python tax.heatmap(data, cmap=None)

This can produces images such as:


Axes Ticks and Orientations

For a given ternary plot there are two valid ways to label the axes ticks corresponding to the clockwise and counterclockwise orientations. However note that the axes labels need to be adjusted accordingly, and ternary does not do so automatically when you pass clockwise=True to tax.ticks().

There is a more detailed discussion on issue #18 (closed).

RGBA colors

You can alternatively specify colors as rgba tuples (r, g, b, a) (all between zero and one). To use this feature, pass colormap=False to heatmap() so that the library will not attempt to map the tuple to a value with a matplotlib colormap. Note that this disables the inclusion of a colorbar. Here is an example:

```python import math from matplotlib import pyplot as plt import ternary

def colorpoint(x, y, z, scale): w = 255 xcolor = x * w / float(scale) ycolor = y * w / float(scale) zcolor = z * w / float(scale) r = math.fabs(w - ycolor) / w g = math.fabs(w - xcolor) / w b = math.fabs(w - z_color) / w return (r, g, b, 1.)

def generateheatmapdata(scale=5): from ternary.helpers import simplexiterator d = dict() for (i, j, k) in simplexiterator(scale): d[(i, j, k)] = color_point(i, j, k, scale) return d

scale = 80 data = generateheatmapdata(scale) figure, tax = ternary.figure(scale=scale) tax.heatmap(data, style="hexagonal", usergba=True) tax.boundary() tax.settitle("RGBA Heatmap") plt.show()

```

This produces the following image:

Unittests

You can run the test suite as follows:

python python -m unittest discover tests

Contributing

Contributions are welcome! Please share any nice example plots, contribute features, and add unit tests! Use the pull request and issue systems to contribute.

Selected Contributors

  • Marc Harper marcharper: maintainer
  • Bryan Weinstein btweinstein: Hexagonal heatmaps, colored trajectory plots
  • chebee7i: Docs and figures, triangular heatmapping
  • Cory Simon: Axis Colors, colored heatmap example

Known-Issues

At one point there was an issue on macs that causes the axes labels not to render. The workaround is to manually call tax._redraw_labels() before showing or rendering the image.

Owner

  • Name: Marc
  • Login: marcharper
  • Kind: user
  • Location: California
  • Company: Google

Data Scientist @Google

Citation (CITATION.md)

# Citation

[![DOI](https://zenodo.org/badge/19505/marcharper/python-ternary.svg)](https://zenodo.org/badge/latestdoi/19505/marcharper/python-ternary)

Please cite as follows:

```
Marc Harper et al. (2015). python-ternary: Ternary Plots in Python. Zenodo. 10.5281/zenodo.594435
```

Bibtex:
```
@article{pythonternary,
  title={python-ternary: Ternary Plots in Python},
  author={Marc Harper et al},
  journal={Zenodo 10.5281/zenodo.594435},
  doi={10.5281/zenodo.594435},
  url={https://github.com/marcharper/python-ternary},
}
```

GitHub Events

Total
  • Issues event: 2
  • Watch event: 39
  • Issue comment event: 2
  • Pull request event: 2
  • Fork event: 3
Last Year
  • Issues event: 2
  • Watch event: 39
  • Issue comment event: 2
  • Pull request event: 2
  • Fork event: 3

Committers

Last synced: over 1 year ago

All Time
  • Total Commits: 364
  • Total Committers: 29
  • Avg Commits per committer: 12.552
  • Development Distribution Score (DDS): 0.316
Past Year
  • Commits: 4
  • Committers: 1
  • Avg Commits per committer: 4.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Marc Harper m****r@g****m 249
Marc m****r 51
btweinstein b****n@g****m 18
tgwoodcock t****k 6
CorySimon c****n@b****u 6
Marc Harper m****r@u****u 3
maximweb m****h@g****e 2
gileshd g****d@g****m 2
chebee7i c****i@g****m 2
Wiley Morgan w****n@g****m 2
Vince Knight v****t@g****m 2
Chuan-Zheng Lee c****e@s****u 2
Nick Swanson-Hysell s****l@b****u 2
mcnixon96 3****6 2
luizkeng p****g@g****m 1
jl-bernal b****l@g****m 1
Dean Chester d****r 1
Keng 5****g 1
Maximiliano Greco m****o 1
SaxonAnglo S****o 1
The Gitter Badger b****r@g****m 1
Todd t****8@g****m 1
ml-evs m****8@c****k 1
c56pony n****r@g****m 1
Zack Gainsforth z****g@g****m 1
Loisaida Sam s****g@g****m 1
Kaarel Mänd k****d@p****m 1
Aaron David Schneider a****r@g****m 1
Guido Zuidhof me@g****o 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 9 months ago

All Time
  • Total issues: 76
  • Total pull requests: 34
  • Average time to close issues: 4 months
  • Average time to close pull requests: about 1 month
  • Total issue authors: 65
  • Total pull request authors: 24
  • Average comments per issue: 2.68
  • Average comments per pull request: 1.15
  • Merged pull requests: 18
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 3
  • Pull requests: 2
  • Average time to close issues: 8 days
  • Average time to close pull requests: about 16 hours
  • Issue authors: 3
  • Pull request authors: 2
  • Average comments per issue: 1.0
  • Average comments per pull request: 0.5
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • marcharper (5)
  • wuyuyu1024 (2)
  • mohamedELamine (2)
  • RihuiAn (2)
  • olgabot (2)
  • machel7 (2)
  • AndrewFalkowski (2)
  • Mr-Liu-CUG (2)
  • forgetmenot9911 (1)
  • xindi-dumbledore (1)
  • DrGFreeman (1)
  • dylanradovic (1)
  • xvcheng (1)
  • carlosgmartin (1)
  • TraceMeGroup (1)
Pull Request Authors
  • marcharper (7)
  • czlee (3)
  • luizkeng (2)
  • sukesh-sh (2)
  • maximweb (2)
  • fairliereese (1)
  • tarinivenkataraman (1)
  • bobmyhill (1)
  • kaarelmand (1)
  • AaronDavidSchneider (1)
  • vegardjervell (1)
  • shree2010 (1)
  • einezahl (1)
  • jordanbCS (1)
  • Radhika-Saini (1)
Top Labels
Issue Labels
enhancement (9) bug (5) confirmed (1) duplicate (1) add-to-documentation (1)
Pull Request Labels
spam (6) enhancement (1)

Packages

  • Total packages: 14
  • Total downloads:
    • pypi 24,954 last-month
  • Total docker downloads: 412
  • Total dependent packages: 13
    (may contain duplicates)
  • Total dependent repositories: 38
    (may contain duplicates)
  • Total versions: 35
  • Total maintainers: 2
pypi.org: python-ternary

Make ternary plots in python with matplotlib

  • Versions: 10
  • Dependent Packages: 12
  • Dependent Repositories: 37
  • Downloads: 24,954 Last month
  • Docker Downloads: 412
Rankings
Dependent packages count: 0.9%
Downloads: 1.5%
Average: 2.3%
Dependent repos count: 2.4%
Stargazers count: 2.4%
Docker downloads count: 2.7%
Forks count: 3.7%
Maintainers (1)
Last synced: 6 months ago
alpine-v3.18: py3-ternary

Make ternary plots in python with matplotlib

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 4.8%
Forks count: 9.1%
Stargazers count: 10.3%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.18: py3-ternary-pyc

Precompiled Python bytecode for py3-ternary

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 4.8%
Forks count: 9.1%
Stargazers count: 10.3%
Maintainers (1)
Last synced: 7 months ago
alpine-edge: py3-ternary

Make ternary plots in python with matplotlib

  • Versions: 4
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Average: 9.0%
Forks count: 9.9%
Stargazers count: 11.7%
Dependent packages count: 14.6%
Maintainers (1)
Last synced: 7 months ago
alpine-edge: py3-ternary-pyc

Precompiled Python bytecode for py3-ternary

  • Versions: 3
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Average: 9.2%
Forks count: 10.4%
Stargazers count: 12.1%
Dependent packages count: 14.1%
Maintainers (1)
Last synced: 7 months ago
conda-forge.org: python-ternary
  • Versions: 8
  • Dependent Packages: 1
  • Dependent Repositories: 1
Rankings
Forks count: 15.1%
Stargazers count: 15.9%
Average: 21.1%
Dependent repos count: 24.4%
Dependent packages count: 29.0%
Last synced: 7 months ago
alpine-v3.21: py3-ternary

Make ternary plots in python with matplotlib

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.19: py3-ternary

Make ternary plots in python with matplotlib

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Maintainers (1)
Last synced: 6 months ago
alpine-v3.21: py3-ternary-pyc

Precompiled Python bytecode for py3-ternary

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.20: py3-ternary

Make ternary plots in python with matplotlib

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.22: py3-ternary-pyc

Precompiled Python bytecode for py3-ternary

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.22: py3-ternary

Make ternary plots in python with matplotlib

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.20: py3-ternary-pyc

Precompiled Python bytecode for py3-ternary

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Maintainers (1)
Last synced: 7 months ago
alpine-v3.19: py3-ternary-pyc

Precompiled Python bytecode for py3-ternary

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Dependent packages count: 0.0%
Average: 100%
Last synced: 7 months ago

Dependencies

setup.py pypi
  • matplotlib >=2