Giter Site home page Giter Site logo

disouzam / ternary_plots Goto Github PK

View Code? Open in Web Editor NEW

This project forked from marcoalopez/ternary_plots

0.0 0.0 0.0 450 KB

[Fork] no-fuss ternary plots in Python (using matplotlib)

Home Page: https://marcoalopez.github.io/ternary_plots/

License: Mozilla Public License 2.0

Python 3.04% HTML 42.40% Jupyter Notebook 54.56%

ternary_plots's Introduction

Brought to you by Marco A. Lopez-Sanchez - Last update: 2022-11-22

What is a ternary plot?

A ternary plot is a triangular diagram that displays the proportion of three variables that sum to a constant, usually 1 or 100%. It is a common diagram in solid-earth but also in other physical sciences.

What is the purpose of this repository?

You want to use ternary diagrams in your Jupyter notebook (or Python script). Sadly you realise that matplolib does not have ternary plots by default. After some research on the internet, you realise that the alternatives are either to install other plotting libraries (e.g. Plotly) or third-party libraries that rely on matplolib (e.g. python-ternary or mpltern). Unfortunately, you don't feel like learning a new syntax for plotting (you are too comfortable with your matplolib buddy) or don't want to install a new Python library with all that this entails (dependencies, etc.) and that it seem overkill for your needs*. This is where the good news comes in. You can create a barebones ternary diagram with the minimum necessary elements in matplolib in few lines of code. In short, no installations, no new dependencies, your usual matplolib syntax, and no fuss.

*I have nothing against these libraries, quite the opposite, if you need more advanced features use them!

How to use it?

Simply copy and paste the functions into your Jupyter notebook cells and follow the usage examples.

# this is the minimum modules you must import to make it work
import matplotlib.pyplot as plt
from types import SimpleNamespace

# also used in the example although not strictly necessary
import numpy as np

Below we define three different Python functions that convert from ternary to Cartesian coordinates

def tri2cartX(upper_apex, right_apex, left_apex):
    """ Converts ternary to Cartesian x coordinates."""
    return 0.5 * (upper_apex + 2 * right_apex) / (upper_apex + right_apex + left_apex)

def tri2cartY(upper_apex, right_apex, left_apex):
    """ Converts ternary to Cartesian y coordinates."""
    return (3**0.5 / 2) * upper_apex / (upper_apex + right_apex + left_apex)

def tri2cart(upper_apex, right_apex, left_apex):
    """ Converts ternary to Cartesian coordinates.
    Normalises input values and returns Cartesian
    coordinates x, y as a float or array.

    Parameters
    ----------
    upper_apex : numeric or array-like
        coordinate related to the upper corner/apex
    right_apex : numeric or array-like
        coordinate related to the right corner/apex
    left_apex : numeric or array-like
        coordinate related to the left corner/apex

    Example
    -------
    x, y = tri2cart(20, 10.5, 3.2)
    """

    # normalize
    total = upper_apex + right_apex + left_apex
    upper_apex = upper_apex / total
    right_apex = right_apex / total
    left_apex = left_apex / total
    
    return tri2cartX(upper_apex, right_apex, left_apex), tri2cartY(upper_apex, right_apex, left_apex)

Finally, the function that create the ternary plot using matplolib

def ternary(upper_label=None, left_label=None, right_label=None, **fig_kw):
    """ No-fuss ternary plot using matplotlib, meaning: A simple
    ternary diagram using matplolib with the minimum necessary
    elements. It requires no other dependencies than matplolib.
    Returns the figure and axe objects with which you can use the
    typical matplotlib functions such as plot(), scatter(), etc.
    Coordinates must be converted from ternary to Cartesian for use.
    See tri2cart() function.

    Parameters
    ----------
    upper_label : str, optional
        the label of the upper corner/apex
    right_label : str, optional
        the label of the right corner/apex
    left_label : str, optional
        the label of the left corner/apex
    """    
    # set grid (each 0.2)
    slines = (# //CB
              SimpleNamespace(x1=tri2cartX(4/5,0,1/5), y1=tri2cartY(4/5,0,1/5),
                              x2=tri2cartX(4/5,1/5,0), y2=tri2cartY(4/5,1/5,0)),
              SimpleNamespace(x1=tri2cartX(3/5,0,2/5), y1=tri2cartY(3/5,0,2/5),
                              x2=tri2cartX(3/5,2/5,0), y2=tri2cartY(3/5,2/5,0)),
              SimpleNamespace(x1=tri2cartX(2/5,0,3/5), y1=tri2cartY(2/5,0,3/5),
                              x2=tri2cartX(2/5,3/5,0), y2=tri2cartY(2/5,3/5,0)),
              SimpleNamespace(x1=tri2cartX(1/5,0,4/5), y1=tri2cartY(1/5,0,4/5),
                              x2=tri2cartX(1/5,4/5,0), y2=tri2cartY(1/5,4/5,0)),
              # //AB
              SimpleNamespace(x1=tri2cartX(0,1/5,4/5), y1=tri2cartY(0,1/5,4/5),
                              x2=tri2cartX(1/5,0,4/5), y2=tri2cartY(1/5,0,4/5)),
              SimpleNamespace(x1=tri2cartX(0,2/5,3/5), y1=tri2cartY(0,2/5,3/5),
                              x2=tri2cartX(2/5,0,3/5), y2=tri2cartY(2/5,0,3/5)),
              SimpleNamespace(x1=tri2cartX(0,3/5,2/5), y1=tri2cartY(0,3/5,2/5),
                              x2=tri2cartX(3/5,0,2/5), y2=tri2cartY(3/5,0,2/5)),
              SimpleNamespace(x1=tri2cartX(0,4/5,1/5), y1=tri2cartY(0,4/5,1/5),
                              x2=tri2cartX(4/5,0,1/5), y2=tri2cartY(4/5,0,1/5)),
              # //AC
              SimpleNamespace(x1=tri2cartX(0,4/5,1/5), y1=tri2cartY(0,4/5,1/5),
                              x2=tri2cartX(1/5,4/5,0), y2=tri2cartY(1/5,4/5,0)),
              SimpleNamespace(x1=tri2cartX(0,3/5,2/5), y1=tri2cartY(0,3/5,2/5),
                              x2=tri2cartX(2/5,3/5,0), y2=tri2cartY(2/5,3/5,0)),
              SimpleNamespace(x1=tri2cartX(0,2/5,3/5), y1=tri2cartY(0,2/5,3/5),
                              x2=tri2cartX(3/5,2/5,0), y2=tri2cartY(3/5,2/5,0)),
              SimpleNamespace(x1=tri2cartX(0,1/5,4/5), y1=tri2cartY(0,1/5,4/5),
                              x2=tri2cartX(4/5,1/5,0), y2=tri2cartY(4/5,1/5,0))
              )
    
    # make plot
    fig, ax = plt.subplots(constrained_layout=True, **fig_kw)
    
    # draw master (triangle) lines
    ax.plot([0, 1], [0, 0], '-', color='black', linewidth=2, zorder=11)
    ax.plot([0, 0.5], [0, 0.8660254], '-', color='black', linewidth=2, zorder=11)
    ax.plot([0.5, 1], [0.8660254, 0], '-', color='black', linewidth=2, zorder=11)
    
    # draw grid lines
    for line in slines:
        ax.plot([line.x1, line.x2], [line.y1, line.y2], '-', color='grey', linewidth=1, zorder=1)
    
    if upper_label is not None:
        ax.text(x=0.5, y=0.91, s=upper_label, fontsize=14, horizontalalignment='center', verticalalignment='top', zorder=11)
        ax.text(x=1.05, y=-0.01, s=right_label, fontsize=14, horizontalalignment='center', verticalalignment='top', zorder=11)
        ax.text(x=-0.05, y=-0.01, s=left_label, fontsize=14, horizontalalignment='center', verticalalignment='top', zorder=11)
    
    # Prettify
    ax.set_axis_off()  # remove the box, ticks, etc.
    ax.axis('equal')  # ensure equal aspect ratio
    
    return fig, ax

Alternatively, you can download the python file containing the functions here and save it to the same folder where your notebook is located. Then simply run the script using %run mpl_ternary.py or import it as a module. More details in https://github.com/marcoalopez/ternary_plots/blob/main/example_two.ipynb

Examples

# show figure primitives
fig, ax = ternary()

primitives

Plotting some points for reference

fig, ax = ternary(upper_label='upper label', left_label='left label', right_label='right label')

ax.plot(tri2cartX(1, 0, 0), tri2cartY(1, 0, 0), 'o', markersize=12, label='(1,0,0)')
ax.plot(tri2cartX(0, 1, 0), tri2cartY(0, 1, 0), 'o', markersize=12, label='(0,1,0)')
ax.plot(tri2cartX(0, 0, 1), tri2cartY(0, 0, 1), 'o', markersize=12, label='(0,0,1)')
ax.plot(tri2cartX(1/3, 1/3, 1/3), tri2cartY(1/3, 1/3, 1/3), 'o', markersize=12, label='the centre')

ax.legend(fontsize=14)

first example

Real life examples

To use ternary diagrams it is always the same two-step process:

  1. Normalise and convert your ternary coordinates to Cartesian ones. For this you will use the tri2cart() function.
  2. Then initialize your ternary diagram using the ternary() function and use your ususal matplolib commands (plot(), scatter(), etc.)

Important: Usage examples will be available soon

License

Creative Commons Licence
The notebooks are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License and codes under Mozilla Public License 2.0.


Copyright © 2022 Marco A. Lopez-Sanchez

Information presented on this website and the notebooks is provided without any express or implied warranty and may include technical inaccuracies or typing errors; the author reserve the right to modify or enhance the content of this website as well as the notebooks at any time without previous notice. This webpage and the notebooks are not liable for the content of external links.

Hosted on GitHub Pages

ternary_plots's People

Contributors

marcoalopez avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.