Skip to content

Commit 4ef3452

Browse files
Update templates tutorial
1 parent 0d39d8c commit 4ef3452

File tree

1 file changed

+108
-7
lines changed

1 file changed

+108
-7
lines changed
Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,115 @@
11
"""
2-
Creating Classification Diagrams
3-
==================================
2+
Creating Plot Templates/Classifier Models
3+
==========================================
44
5-
* Create JSON files
6-
* Add util.classification
7-
* Add plot.templates file
5+
:mod:`pyrolite` provides a system for creating and using plot templates/classifier models
6+
based on a series of polygons in variable space (e.g., the TAS diagram). A variety of
7+
`diagram templates <../examples/plotting/templates.html>`__/ `classifiers <../examples/util/TAS.html>`__
8+
are available, but you can also create your own.
89
10+
In this tutorial, we'll go through the process of creating a diagram template from scratch,
11+
as a demonstration of how you might create your own for your use - or to later contribute
12+
to the collection in pyrolite.
913
"""
1014

1115
#######################################################################################
12-
# First let's pull in a simple dataset to use throughout these examples:
16+
# The basis for most diagrams and classifiers is the class
17+
# :class:`~pyrolite.util.classification.PolygonClassifier`; the docstring-based help
18+
# text is a good place to start to understand what we'll need to put it together:
1319
#
14-
from pyrolite.util.synthetic import normal_frame
20+
from pyrolite.util.classification import PolygonClassifier
21+
22+
help(PolygonClassifier)
23+
#######################################################################################
24+
# The key things you'll need to construct a classifer are:
25+
#
26+
# 1. a name
27+
# 2. a specification of what the axes correspond to,
28+
# 3. and a dictionary of fields (dictionaries containing a 'name' and coordinates defining the polygon).
29+
#
30+
# We can also optionally specify the x and y limits, which are specific to plotting.
31+
# Here we'll put together a simple classifier model with just two fields,
32+
# and add this to a :mod:`matplotlib` axis. You can optionally specify names/labels for each field, \
33+
# here we opt to just use some basic IDs (A and B), so these are what will be added to the plot:
34+
#
35+
36+
clf = PolygonClassifier(
37+
name="DemoClassifier",
38+
axes={"x": "SiO2", "y": "MgO"},
39+
fields={
40+
"A": {
41+
"poly": [[0, 75], [0, 100], [50, 100], [50, 75]],
42+
},
43+
"B": {
44+
"poly": [[0, 25], [0, 75], [25, 75], [25, 25]],
45+
},
46+
},
47+
xlim=(0, 100),
48+
ylim=(0, 100),
49+
)
50+
ax = clf.add_to_axes(add_labels=True)
51+
ax.figure
52+
#######################################################################################
53+
# While we're individually passing each of these arguments to
54+
# :class:`~pyrolite.util.classification.PolygonClassifier`, we can also pass a dictionary
55+
# of keyword arguments:
56+
#
57+
cfg = dict(
58+
name="DemoClassifier",
59+
axes={"x": "SiO2", "y": "MgO"},
60+
fields={
61+
"A": {
62+
"poly": [[0, 75], [0, 100], [50, 100], [50, 75]],
63+
},
64+
"B": {
65+
"poly": [[0, 25], [0, 75], [25, 75], [25, 25]],
66+
},
67+
},
68+
xlim=(0, 100),
69+
ylim=(0, 100),
70+
)
71+
72+
clf = PolygonClassifier(**cfg)
73+
#######################################################################################
74+
# Each of the built-in models are saved as JSON files, and loaded in a manner as above;
75+
# we can replicate that here - saving our configuration to JSON then loading it up again.
76+
# We'll use a temporary directory here, but you can save it wherever you like (note the
77+
# :mod:`pyrolite` templates live under `/data/models` in the repository); once you've
78+
# got a template working how you'd like, consider
79+
# `submitting it <../../dev/contributing.html>`__!
80+
#
81+
import json
82+
83+
from pyrolite.util.general import temp_path
84+
85+
tmp = temp_path()
86+
with open(tmp / "demo_classifier.json", "w") as f:
87+
f.write(json.dumps(cfg))
88+
89+
90+
with open(tmp / "demo_classifier.json", "r") as f:
91+
clf = PolygonClassifier(**json.load(f))
92+
93+
clf.add_to_axes(add_labels=True).figure
94+
#######################################################################################
95+
# Ternary Templates
96+
# ~~~~~~~~~~~~~~~~~
97+
#
98+
# While it's slightly more work, you can also generate ternary templates using a very
99+
# simliar pattern to the bivariate ones above. The principal differences are that you'll
100+
# need to specify three axes (t, l, r), specify a 'ternary' transform, and have coordinates
101+
# for polygons in the ternary space - each with three values. For example,
102+
# here are two fields from the UDSA soil texture triangle:
103+
#
104+
cfg = {
105+
"axes": {"t": "Clay", "l": "Sand", "r": "Silt"},
106+
"transform": "ternary",
107+
"fields": {
108+
"sand": {"name": "Sand", "poly": [[0, 100, 0], [10, 90, 0], [0, 85, 15]]},
109+
"loamy-sand": {
110+
"name": "Loamy Sand",
111+
"poly": [[10, 90, 0], [0, 85, 15], [0, 70, 30], [15, 85, 0]],
112+
},
113+
},
114+
}
115+
PolygonClassifier(**cfg).add_to_axes(add_labels=True).figure

0 commit comments

Comments
 (0)