Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

area filling #106

Open
altanir84 opened this issue Jul 12, 2019 · 6 comments
Open

area filling #106

altanir84 opened this issue Jul 12, 2019 · 6 comments

Comments

@altanir84
Copy link

Great code.

Would be very helpfull to implement the tax.fill() feature, to create base plots with filled areas, like the Dickinson, 1970 Qt ternary plot. Thank you!

@vmeschke
Copy link

vmeschke commented May 9, 2021

I manually implemented this by using some of the code for 'background' fill!

@marcharper
Copy link
Owner

Hi @vmeschke, do you want to share / contribute an example?

@vmeschke
Copy link

@marcharper I would love to! What's the best way to do so?

@marcharper
Copy link
Owner

@vmeschke If you have an image and some code to generate it, you can add it to the examples directory. Otherwise you can paste the info here and I'll add it.

@vmeschke
Copy link

vmeschke commented Jul 1, 2021

Here's an example of code and the filling demo! I just modified the tax.fill method to take an unspecified number of points. I can talk more/add additional comments if helpful.
filled_ternary

Code:
import ternary
import pandas as pd
import math
import itertools
import numpy as np
from pymatgen.core import Element, Composition
from matplotlib import cm
import matplotlib.pyplot as plt

def permute_point(p, permutation=None):
"""
Permutes the point according to the permutation keyword argument. The
default permutation is "012" which does not change the order of the
coordinate. To rotate counterclockwise, use "120" and to rotate clockwise
use "201"."""
if not permutation:
return p
return [p[int(permutation[i])] for i in range(len(p))]

def unzip(l):
"""[(a1, b1), ..., (an, bn)] ----> ([a1, ..., an], [b1, ..., bn])"""
return list(zip(*l))

def project_point(p, permutation=None):
"""
Maps (x,y,z) coordinates to planar simplex.
Parameters
----------
p: 3-tuple
The point to be projected p = (x, y, z)
permutation: string, None, equivalent to "012"
The order of the coordinates, counterclockwise from the origin
"""
permuted = permute_point(p, permutation=permutation)
a = permuted[0]
b = permuted[1]
x = a + b/2.
y = (np.sqrt(3)/2) * b
return np.array([x, y])

def fill_region(ax, color, points, pattern=None, zorder=-1000, alpha=None):
"""Draws a triangle behind the plot to serve as the background color
for a given region."""
vertices = map(project_point, points)
xs, ys = unzip(vertices)
poly = ax.fill(xs, ys, facecolor=color, edgecolor=color, hatch=pattern, zorder=zorder, alpha=alpha)
return poly

def main():
scale = 100
fontsize = 12
figure, tax = ternary.figure(scale=scale)
tax.gridlines(color="grey", multiple=10)

# corner points of the regions. Any number of points works.
regions = [[(0, 0, 100), (25, 0, 75), (25, 50, 25)],
            [(25, 0, 75), (50, 50, 0), (30, 40, 30), (25, 50, 25)],
            [(50, 50, 0), (43, 57, 0), (25, 50, 25), (70, 10, 20)],
            [(40, 50, 10), (28.57, 71.43, 0), (25, 50, 25), (10, 80, 10), (20, 30, 50)]]

# Generating colors for the regions
cmap = cm.plasma
colorlist = []
for i in np.arange(0,1,1/len(regions)):
    colorlist.append(cmap(i))

# generate the filled regions and make them all different colors
colorindex = 0
for r in regions:
    fill_region(tax.get_axes(), color=colorlist[colorindex], points=r, alpha=.7)
    colorindex += 1

# Final plot formatting
tax.boundary(linewidth=2)
tax.get_axes().axis('off')
tax.clear_matplotlib_ticks()
tax.get_axes().set_aspect(1)
tax._redraw_labels()
tax.savefig('filled_ternary.png')

if name == 'main':
main()

@vmeschke
Copy link

vmeschke commented Jul 1, 2021

If you add the following code to the 'ternary_axes_subplot.py' file, you should be able to call tax.fill_region() with the proper arguments and have it work ok. It works locally for me.

Additional Import:
from .helpers import unzip

Method:

    def fill_region(self, color, points, pattern=None, zorder=-1000, alpha=None):
        """Draws a triangle behind the plot to serve as the background color
        for a given region."""
        ax = self.get_axes()
        vertices = map(project_point, points)
        xs, ys = unzip(vertices)
        poly = ax.fill(xs, ys, facecolor=color, edgecolor=color, hatch=pattern, zorder=zorder, alpha=alpha)
        return poly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants