Giter Club home page Giter Club logo

python-ternary's Introduction

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:

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:

    pip install python-ternary

With setup.py

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

    git clone [email protected]: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:

    fig, tax = ternary.figure()

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

    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:

    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

    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.

    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:

    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)],

    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:

    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:

    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:

    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:

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

or on a TernaryAxesSubplot object:

    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:

import math
from matplotlib import pyplot as plt
import ternary

def color_point(x, y, z, scale):
    w = 255
    x_color = x * w / float(scale)
    y_color = y * w / float(scale)
    z_color = z * w / float(scale)
    r = math.fabs(w - y_color) / w
    g = math.fabs(w - x_color) / w
    b = math.fabs(w - z_color) / w
    return (r, g, b, 1.)


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


scale = 80
data = generate_heatmap_data(scale)
figure, tax = ternary.figure(scale=scale)
tax.heatmap(data, style="hexagonal", use_rgba=True)
tax.boundary()
tax.set_title("RGBA Heatmap")
plt.show()

This produces the following image:

Unittests

You can run the test suite as follows:

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.

python-ternary's People

Contributors

aarondavidschneider avatar btweinstein avatar c56pony avatar chebee7i avatar corysimon avatar czlee avatar deanchester avatar drvinceknight avatar gileshd avatar gitter-badger avatar gzuidhof avatar kaarelmand avatar loisaidasam avatar luizkeng avatar marcharper avatar maximweb avatar mcnixon96 avatar ml-evs avatar mmngreco avatar saxonanglo avatar swanson-hysell avatar tgwoodcock avatar toddrme2178 avatar tomreclik avatar wsmorgan avatar zgainsforth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-ternary's Issues

Ternary surface plot

Hey guys,

I am working on a piece of code which can visualize the ternary plot via a surface. I wonder if this project have any plan to implement such functions.
figure_1

Best wishes!

get -> git

In readme file,

get clone [email protected]:marcharper/python-ternary.git
cd python-ternary
sudo python setup.py install

I suppose the get here is really git.

Bug in ticks()

In lines.py, I think there is a bug, where it is assumed that ticks is a boolean, but I think it is either None or a list/array. Thus, I think we should change it to below. I got an error when I passed custom ticks to this function because of these, and it works now with this change.

@@ -224,13 +224,13 @@ def ticks(ax, scale, ticks=None, locations=None, multiple=1, axis='b',
     if not axis_chars.issubset(valid_axis_chars):
         raise ValueError("axis must be some combination of 'l', 'r', and 'b'")

-    if ticks and not locations:
+    if ticks is not None and locations is None:
         num_ticks = len(ticks)
         if num_ticks != 0:
             multiple = scale / (num_ticks - 1)
             locations = arange(0, scale + multiple, multiple)

-    if not ticks:
+    if ticks is None:
         locations = arange(0, scale + multiple, multiple)
         ticks = locations

UPDATE: Also, I didn't take the time to understand why you need ticks and locations. Could we just remove the locations and use only ticks=None for default ticks, ticks=[] for no ticks and ticks=arange(23) for example, for custom ticks.

python 3.k ipython 4.1 import error

When I try import the packege get this import error:

import ternary

---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-fe0219fb98b4> in <module>()
      3 import matplotlib.pyplot as plt
      4 import seaborn as sns
----> 5 import ternary

/Users/mmngreco/anaconda/envs/py3/lib/python3.4/site-packages/python_ternary-0.0.1-py3.4.egg/ternary/__init__.py in <module>()
----> 1 from plotting import (
      2     clear_matplotlib_ticks,
      3     plot,
      4     resize_drawing_canvas,
      5     scatter,

ImportError: No module named 'plotting'

Version:
3.4.3 |Continuum Analytics, Inc.| (default, Mar 6 2015, 12:07:41)
[GCC 4.2.1 (Apple Inc. build 5577)]

axis order confution

Thanks for a cool project...

I was fooling around with the possibilities, because I needed a quick ternary poly, and my R have become rusty...
More specifically I tried the following minimalistic code:

from matplotlib import pyplot

import ternary

if __name__ == '__main__':

    scale = 100
    fontsize = 10
    col_axis = {'b': 'g', 'l': 'r', 'r':'b'}

    figure, tax = ternary.figure(scale=scale)
    figure.set_size_inches(10, 10)
    tax.clear_matplotlib_ticks()

    tax.set_title("mini tern", fontsize=20)

    tax.boundary(linewidth=1.0)
    tax.bottom_axis_label("X-axis", fontsize=fontsize, color=col_axis['b'])
    tax.right_axis_label("Y-axis", fontsize=fontsize, color=col_axis['r'])
    tax.left_axis_label("Z-axis", fontsize=fontsize, color=col_axis['l'])

    tax.gridlines(multiple=10, linewidth=2,
              horizontal_kwargs={'color':col_axis['b']},
              left_kwargs={'color':col_axis['l']},
              right_kwargs={'color':col_axis['r']},
              alpha=0.7)

    lst_pnts = [[10,10,80],[20,60,20],[40,30,30]]
    tax.scatter(lst_pnts, marker='D', color='black')
    for pnt in lst_pnts:
        tax.annotate(str(pnt),pnt)

    pyplot.show()

I works in the sense that it produces a plot, and give no error messages.
But I can't say that I agree with the plot...
For any (x,y,z) coordinate I would the bottom (horizontal) axis to be x-axis, indexed from left to right, like in any classic 2D coordinate system.
I would then assume the right axis to be y-axis, indexed from bottom up. And finally the left axis to be z-axis, indexed top down, to complete the circle.

This seems to be perfect, when I try to read out the three points in my example [10,10,80],[20,60,20],[40,30,30]. And the green-blue-red colouring of the axis-lables follow the same standard.

But the colouring og the grid-lines seem to slant to the wrong side?

Can you please tell me if I'm doing this wrong, or maybe understanding the concept wrong.

Best regards
Martin Hvidberg
figure_1

Ask: Sharing the same color-bar between several ternary graphs

I want to share color-bar between several ternary graphs which have individual value-range.
For example, value-range of graph A is (0, 67), value-range of graph B is (65, 202)
I want the color-bar which fits both of graph A and graph B.

Now, I have two color-bars and set of (color and number) does not match between A and B

Ticks orientation

Im sorry for post this issue as it has been discussed before but things does not work the way i expected.

import pylab as p
import ternary as t

figure, d=t.figure(scale=1)

d.boundary(linewidth=2.0)
d.gridlines(multiple=0.1,color="blue",linewidth=0.8)

d.set_title(r"source flavour composition $\nu_e,\nu_\mu,\nu_\tau$",fontsize=20)
d.left_axis_label(r"$\nu_\tau$",fontsize=20,offset=0.12)
d.right_axis_label(r"$\nu_\mu$",fontsize=20)
d.bottom_axis_label(r"$\nu_e$",fontsize=20)
d._redraw_labels()

d.ticks(axis='brl',multiple=0.1)
p.axis('off')
point1=[(0.34669820676138435,0.3336302826666826,0.31967151057193305)]
d.scatter(point1, marker='D', color='green', label=r"$(\frac{1}{3},\frac{2}{3},0)$")
d.resize_drawing_canvas(scale=1.05)
d.legend()
d.show()

untitled

from the plot above, the point i plotted corresponds to the 3 value in point1, but if I were to read off from the plot the ticks labels are reversed. from @marcharper u suggested adding an argument to ticks, so i tried but it gave me error when i replace the ticks line to

d.ticks(axis='brl',multiple=0.1,ticks=[1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0])

TypeError: 'NoneType' object is not iterable

apologies again as this has been discuss before, but is annoying that the orientation of tick does not show the correct value I'm plotting.

edit: the value in point 1 correspond nu e,mu,tau respectively.

How to change the size of text of color label?

How to change the size of text of color label in using heatmap?
I searched in previous discussions, but could not find it.

I think if I can get the object of colorbar, I can change the fontsize of it by using an order like below.
"ax.set_yticklabels( fontsize=10)"
,but I don't know how to get it.

And another question, in this case, what is corresponding to the "im" in the code below?
When putting one color bar to subplots, "im" is needed to have the colorbar, but again I cannot find it.

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)
fig.colorbar(im, ax=axes.ravel().tolist())
plt.show()

Minor issue. How do I turn the ternary plots ticks inwards?

I wanted to know if there is a parameter in the ticks attribute tax.ticks(axis='lbr', linewidth=1, multiple=0.1), to give the direction of the ticks for the ternary plot. I was thinking something similar to tax.ax(axis = 'y', direction = 'in').

The plot generated by `heatmap` is not equilateral

Here is the code I used to generate a ternary plot:

import ternary
scale = N

fig, ax = plt.subplots()
ax.axis("off")
figure, tax = ternary.figure(scale=scale, ax=ax)

tax.heatmap(heatmap_dict, cmap=None)

figure.set_size_inches(10, 10)

tax.boundary(linewidth=2.0)
tax.set_title("$W12$")

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

# Remove default Matplotlib Axes
tax.clear_matplotlib_ticks()

tax.show()

where heatmap_dict is a dictionary mapping (i,j) to a value. See the figure below for the generated plot. Obviously the bottom side is shorter than either of the other two sides. I noticed that this feature is also present in the documentation of this package.

produce_figures_ipynb_-code-___of3_code

Implementation with Scipy ConvexHull

I am trying to place a bounding polygon/surface around my plotted data points. I have tried to implement this using ConvexHull from the scipy package but I am running into trouble. Any ideas or suggestions for implementing something like this? I have found a simple example below (assume that the polygons form around the outermost data points for each dataset.
image

Heatmap polygon triangles don't meet exactly

Hey Marc,

Lovely library. I've used it to make some great heatmaps from a data dictionary.
Just thought I'd file a bug report as the triangles don't quite match up if you zoom in - its really noticeable if you remove gridlines and have a low scale.

Cheers,
J.

Axis labels not working for me

Great tool. I will cite this in my paper! Oddly,

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)

do not work for me...

EDIT: I just needed to type:

tax._redraw_labels()

but it would be good to not have to do this.

Investigate Matplotlib transformations

Right now the library is best described as a wrapper around matplotlib. It may be better to integrate more deeply with matplotlib using transformations.

incompatible bar label

Dear Marc,

I am trying your example code colorbar_kwargs.py for my system. I am willing to plot my ternary phase diagram with calculated free energies. I have tried for some test case and realized that the free energy (i.e scatter points c values) are not really compatible with bar label. For instance, I have selected 3 points with 0, -5 and -9.5 values (in vmin=-10, vmax=0 range ).
`# Scatter some points
points = [(2,3,5),(2,1,7),(2,5,2)]
c = [0, -5, -9.5]

cb_kwargs = {"shrink" : 0.6,
"orientation" : "horizontal",
"fraction" : 0.1,
"pad" : 0.05,
"aspect" : 30}

tax.scatter(points,marker='s',c=c,edgecolor='k',s=80,linewidths=0.5,
vmin=-10, vmax=0, colorbar=True,colormap='jet',cbarlabel='Free Energy (eV)',
cb_kwargs=cb_kwargs,zorder=3)`

Under that circumstances I suppose to have blue, green and red circles in the phase diagram, but this is not the case as seen in the image attached.

If you can give me a feedback, I will be appreciated.
Thanks,
Halil

test

example_scatter_colorbar.py on mac

Hello,

I am getting this issue using example_scatter_colorbar.py on my mac with matplotlib version 1.5.1:

File "/usr/local/lib/python2.7/site-packages/matplotlib/artist.py", line 856, in update
raise AttributeError('Unknown property %s' % k)
AttributeError: Unknown property colorbar

python3.5 ipython4 ternary.figure error

I try implement the example of your README.md but I get this tracebak:

from matplotlib import pyplot
import ternary

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

# Draw Boundary and Gridlines
tax.boundary(color="black", linewidth=2.0)
tax.gridlines(color="blue", multiple=5) # Every 5th gridline, can be a float

# 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
ternary_ax.ticks(axis='lbr', color="black", linewidth=1)

# Remove default Matplotlib Axes
tax.clear_matplotlib_ticks()

pyplot.show()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-081775008589> in <module>()
      4 ## Boundary and Gridlines
      5 scale = 40
----> 6 figure, tax = ternary.figure(scale=scale)
      7 
      8 # Draw Boundary and Gridlines

AttributeError: module 'ternary' has no attribute 'figure'

Code crashes when drawing axes

Here is the traceback. The outer function is just a wrapper of mine, and doesn't set the axes colors.

TypeError                                 Traceback (most recent call last)

in ()
2 figure, tax = ternary.figure( scale=scale )
3
----> 4 plotPreferences( tax, 'Sig', players, [4], [0,1,2,3,4,5] )

in plotPreferences(tax, agentType, agent, runList, inputList, colors)
12 tax.bottom_axis_label("Preference for 2", fontsize=fontsize)
13
---> 14 tax.boundary(color="black", linewidth=2.0)
15 tax.gridlines(multiple=0.1, color="blue")
16 tax.ticks(axis='lbr', color="black", linewidth=1, multiple=0.1)

C:\Users\Peter\Anaconda3\lib\site-packages\ternary\ternary_axes_subplot.py in boundary(self, scale, axes_colors, *_kwargs)
201 ax = self.get_axes()
202 self.resize_drawing_canvas(scale)
--> 203 lines.boundary(scale=scale, ax=ax, axes_colors=axes_colors, *_kwargs)
204
205 def gridlines(self, multiple=None, horizontal_kwargs=None, left_kwargs=None,

C:\Users\Peter\Anaconda3\lib\site-packages\ternary\lines.py in boundary(ax, scale, axes_colors, *_kwargs)
119 axes_colors[_axis] = 'black'
120
--> 121 horizontal_line(ax, scale, 0, color=axes_colors['b'], *_kwargs)
122 left_parallel_line(ax, scale, 0, color=axes_colors['l'], *_kwargs)
123 right_parallel_line(ax, scale, 0, color=axes_colors['r'], *_kwargs)

TypeError: horizontal_line() got multiple values for keyword argument 'color'

Scatterplot over Heatmap

Is it possible to put a scatterplot over a heatmap? Whenever I try, the heatmap covers the points. Is there some way to control what ends up on top?

User-Specified Coordinate System

The current heatmap code places 001 at the lower left, while project_point places 100 at the lower left. My thought was that these conventions should match just in case you want to scatter and color polygons on the same MPL axis.

More generally, it might be nice if the user could specify which coordinate system to use when plotting. For an upright simplex, we can call the corners left, center, right. The user might designate which coordinate system to use by specifying one of: {'xyz', 'yzx', 'zxy', 'xzy', 'zyx', 'yxz'}. So for 'xyz', x = (1, 0, 0) is assigned to the left corner, y = (0, 1, 0) to the center, and z = (0, 0, 1) to the right corner. 'xyz' is probably going to the preferred one almost always.

Set vmax and vmin based on vertices_values

If vmax or vmin is not given for the heatmap plot. In my opinion the value should represent the maximal and minimal plotted value instead of the maximal and minimal value of the given data.

This changes the plot if the triangular style is used. If just one data value is extremely high or low only a small range of the colorbar is used.

I could try to make a PR which fixes this behavior.

Including a ternary plot as a subplot

Hi,

Thanks for developing the package! The ternary plots look great.
I was wondering how to place another figure (e.g., a scatter plot) beside the ternary plot in matplotlib, but I couldn't quite get the axes handles to work. This is the code I currently have:

import ternary
import numpy.random as rand

def random_points(num_points=25):
    points = []
    for i in range(num_points):
        x = rand.uniform()
        y = rand.uniform(low=0, high=1-x)
        z = 1 - x - y
        points.append((x, y, z))
    return points

figure = plt.figure(figsize=(16, 7))
fig = figure.add_subplot(121)

fig, tax = ternary.figure(scale=1)
fig.set_size_inches(8, 7)
tax.boundary(linewidth=2.0)
tax.gridlines(multiple=.1, color="blue")
points = random_points(30)
tax.scatter(points, marker='s', color='red', label="Red Squares")
points = random_points(30)
tax.scatter(points, marker='D', color='green', label="Green Diamonds")
tax.legend(fontsize=15)
tax.ticks(axis='lbr', linewidth=1, multiple=.1)
tax.clear_matplotlib_ticks()
tax._redraw_labels()

ax = figure.add_subplot(122)
ax.scatter(range(10), range(10))  # Any plot ...

figure.savefig('ternary.pdf')
plt.close('all')

Any suggestions would be greatly appreciated!

Floats for ticks

I've found that 1.0.3 version converts all float ticks to integer which cause example examples/color_coded_heatmap.py to produce ticks 0,0,0,0,0,0,0,0,0,0,1 instead of 0.0,0.1,0.2,...1.0. This does not happen in version 1.0.1.

Different range for three axes

I need to plot ternary figure with different range in three axes. I am not sure it is a common need in this kind of figure. If it is, maybe we can add this feature.

ternary

Ternary.figure() - AttributeError: 'module' object has no attribute 'figure'

Hi,

I have the following error when using

import ternary
ternary.figure()

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'figure'

I am running Windows 7 and have tried to install the python-ternary module on several different python versions (none are registered in systems environments to ensure that it doesnt break ArcGIS python version).

First I tried the command on two versions of Python 2.7.8 related to ArcGIS (32 & 64bit)

Then i've tried in relation to different Anaconda versions

Anaconda3-4.0.0-Windows-x86.exe (Python 3.5.1)
Anaconda3-4.0.0-Windows-x86_64.exe (Python 3.5.1)
Anaconda2-4.0.0-Windows-x86.exe (Python 2.7.11)
Anaconda2-4.0.0-Windows-x86_64.exe (Python 2.7.11)

All reproduce the same error message...

Alternative Mapping for Heatmaps

Attached is crude plot of my understanding for how the heatmaps are calculated using triangular lattices. Essentially, each point is assigned to the lower-left corner of an upright triangle. The upside-down triangles are the averages of the upright triangles around them.

This makes sense and is probably the easiest thing to do, but the result can be a bit counter intuitive in that a grid at scale s was put on the simplex while a grid at scale s+1 is used for coloring. As an alternative, it might be nice to color each triangle to be the average of the points around it at the same scale (as shown in the bottom diagram). I might be able to tackle this in a week or so, but I thought I'd open an issue anyway.

text5973

Piper Plot

I frequently use a special combination ternary diagram called a "Piper Plot" link. This is used frequently in Earth/Environmental sciences but I have not found a means to generate one in Python. Do you think it is something you might pursue?
Cheers

Not able to remove frame

Hello,

I have tried to remove the frame with

frameon = False

But nothing changed, any ideas ?

Box around plot

Hello,
I've tried to follow your examples to make a ternary plot with some success. However when i create a plot with some long or large font axis labels, a box surrounding the plot does not resize and cuts through the labels. Is there a specific option which is controlling this box size or rescaling it?
I've appended the code and a copy of the figure.
I'm using matplotlib v1.5.1 and python 2.7
Thanks in advance,
Jeremy

fig

import matplotlib
from matplotlib import pyplot, gridspec
import ternary

line = [[.1,.2,.7],[.5,.1,.4]]

Boundary and Gridlines

Plot Various lines

scale = 1
figure, ternary_ax = ternary.figure(scale=scale)

Draw Boundary and Gridlines

ternary_ax.boundary(linewidth=2.0)
ternary_ax.gridlines(color="blue", multiple=0.1)

Set Axis labels and Title

fontsize = 20
ternary_ax.set_title("Long title", fontsize=20)
ternary_ax.left_axis_label("longer title...", fontsize=fontsize, offset=0.2)
ternary_ax.right_axis_label("blah blah blah", fontsize=fontsize, offset=0.2)
ternary_ax.bottom_axis_label("more stuff here", fontsize=fontsize, offset=-0.2)
ternary_ax.plot(line, linewidth=2.0, label="line")
ternary_ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.2)
ternary_ax.clear_matplotlib_ticks()
ternary_ax.ticks(axis='lbr', multiple=0.1, linewidth=1, offset=0.03)
ternary_ax.show()

Are the ticks oriented incorrectly?

Place your finger somewhere in the interior of the triangle. The way the ticks angle into the boundary of the triangle (the axes) suggests that the composition does not add up to 1.0... I think the ticks are oriented in incorrect angles. Am I right?

tertiary_diagram

import ternary
scale = 10

figure, tax = ternary.figure(scale=scale)
tax.left_axis_label("Component 1", offset=0.15)
tax.right_axis_label("Component 0", offset=0.15)
tax.bottom_axis_label("Component 2", offset=-0.05)
tax.heatmapf(iast_loadings_component_0, boundary=False, 
             style="hexagonal", cmap=plt.cm.get_cmap("Blues"), vmax=10.0, vmin=0.0)
tax.boundary(linewidth=2.0)
tax.gridlines(color="blue", multiple=1) # Every 5th gridline, can be a float
# Set ticks
# tax.ticks(axis='lbr', color="black", linewidth=1)
tax.ticks(axis='lbr', color="black", linewidth=1, locations=np.arange(scale+1),
         ticks=["%.1f" % (1.0 * i / scale) for i in range(scale+1)], offset=0.03)
# Remove default Matplotlib Axes
# tax.line(p1, p2, linewidth=3., marker='s', color='green', linestyle=":")
tax._redraw_labels()
tax.set_title("Uptake, component 1", y=1.08)

tax.clear_matplotlib_ticks()
plt.tight_layout()
plt.savefig("Tertiary_diagram.png", format='png', dpi=300, facecolor=fig.get_facecolor())
tax.show()

labels not working

The following code does not produce labels for me. I get the plot, but without any labels.

scale, fontsize = 1, 12
import matplotlib.pyplot as pyplot
figure, ax = pyplot.subplots()
tax = ternary.TernaryAxesSubplot(ax=ax)

tax.set_title("Evolution of 6-6-3 signaler games under ambiguity", 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)

tax.boundary(color="black", linewidth=2.0)
tax.gridlines(multiple=0.1, color="blue")

tax.plot( ((0.1,0.8,0.1),(0.8,0.1,0.1)) )

#tax.scatter( x, marker='s')
tax.legend()
tax.ticks(axis='lbr', color="black", linewidth=1, multiple=0.1)

tax.show()

Contour Plots

Add contour plots, likely using Affine2D and matplotlib's built-in contour functions.

Labels miss in saved picture when not calling plt.show()

If i try to save the plot from the tutorial the following way no labels are shown in the saved plot.

    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()
    tax.savefig("test.png")
    ternary.plt.show()

what fixes the problem is to save the picture after displaying it

    ternary.plt.show()
    tax.savefig("test.png")

The problem is that I am forced to call plt.show() to save the labels in my graph.
It should be not be necessary to call plt.show().

Add non-equal axis scales

Ah this is so close to exactly what I need for ternary plotting, but I have the issue that the bottom axis needs to be of a very different scale than the others. I can do the variable transformation myself, but I'd rather not if I can avoid it.

Anyway, my use case is this:
bottom axis goes from 0 to 1000, left axis goes from 1000 to 3000, right axis goes from 2 to 6.

It seems that is not possible so far as I can tell? That's how I understand this comment: https://github.com/marcharper/python-ternary/blob/master/examples/custom_axis_scaling.py#L22-L29

Spotty Compatibility with Python 2.7

Running first sample snippet crashes:

Traceback (most recent call last):
File "monte/ternar-traj.py", line 13, in
ternary_ax.gridlines(color="black", multiple=0.2)
NameError: name 'ternary_ax' is not defined

Running second snippet generates plot, but out of all the lines only the green line renders, and the axis labels disappear.

markersize not recognised

When using tax.scatter, markersize cannot be specified in the arguments. The following error occurs:

AttributeError: Unknown property markersize

Clear the plot

Hello,
thank you very much for the development of the package. It's helping me a lot.
I am having some difficulties clearing the figures while I am writing and saving them dynamically, because I can't get clf() or close() working. So right now, data points from previous loops are piling up in later figures. I hope, I made my example readable... (I am working with subplots though I don't really need it to fulfill some required formatting, that I haven't been able to accomplish without it):

import ternary
import matplotlib.pyplot as plt

list1 = ...
list2 = ...
list3 = ...
list4 = ...
marker_list = ...
color_list = ...

for val1 in list1:
    for val2 in list2: 
        for val3 in list3:
             w0 = ... # val2 and val3 required
             w1 = ... # val2 and val3 required
             w2 = ... # val2 and val3 required
             point_dict[val3].append((w0,w1,w2))

    # Boundary and Gridlines
    scale = 1.0
    figure, ax = plt.subplots(figsize=(12,10.5))
    tax = ternary.TernaryAxesSubplot(scale=scale,ax=ax)

    # Draw Boundary and Gridlines
    ...
    # Set Axis labels and Title
    ...

    # Plot in different styles with a legend
    for val3 in list3:
        tax.scatter(point_dict[list3[val3]], marker=marker_list[val3], 
                        color=color_list[val3],label=item)
            
    file_title = str(list4[val1])
    print file_title
    tax._redraw_labels()
    plt.savefig(file_title+'K.png')
    plt.close('all')
    plt.clf()

Whatever I fill in in the last lines, it won't reset the plot. However, it must be reset before I enter loop 1 ('for val1 in list1:') again. Right now, my only choise is to run and exit the .py to change val1 manually.

Any suggestions would be appreciated!

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.