diff --git a/.gitignore b/.gitignore
index 0d20b64..2c08ef6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,10 @@
*.pyc
+
+# general things to ignore
+build/
+dist/
+*.egg-info/
+*.egg
+*.py[cod]
+__pycache__/
+*.ipynb_checkpoints/
diff --git a/README.md b/README.md
index 4db5e77..3de6c7d 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,8 @@ The library provides functions for plotting projected lines, curves (trajectorie
-
+
+
@@ -394,6 +395,58 @@ do so automatically when you pass `clockwise=True` to `tax.ticks()`.
There is a [more detailed discussion](https://github.com/marcharper/python-ternary/issues/18)
on issue #18 (closed).
+# Custom Axis Data Limits
+
+By default, the axes limits are [0, scale] i.e. simplex coordinates but it is possible to set
+custom data limits to the axes instead. This is done by passing a dict into set_axis_limits.
+The keys are b, l and r for the three axes and the values are a list of the min and max in
+data coords for that axis. max-min for each axis is the same as the scale i.e. 9 in this case.
+
+```python
+tax.set_axis_limits({'b': [60, 75], 'l': [15, 30], 'r': [10, 25]})
+```
+
+This can be used to zoom in on a particular region, for example. Please see
+the [custom axis scaling example](examples/custom_axis_scaling.py) for further
+details.
+
+
+
+
+
+# Truncated Simplex
+
+One or more corners can be removed from the simplex by setting a truncation.
+This may be useful for saving whitespace if the data are grouped in one area
+of the plot. A truncation is specified in data coordinates by passing a dict
+into tax.set_truncation. The keys are two letters specifying the start and end
+axes of the truncation line and the values give the maximum of the first axis
+specified in data coordinates. For the example on the left below, we write:
+
+```python
+tax.set_truncation({'rl' : 8})
+```
+
+The result is that the truncation line has been drawn from the right axis at
+data coordinate 8 to the left axis, cutting off the top corner. As the figure is no
+longer a triangle, we need to get and set custom axis ticks and tick labels.
+There are convenience functions for this in the case of a truncation and/or
+custom axis data limits. Again for the left image shown below:
+
+```python
+tax.get_ticks_from_axis_limits(multiple=2)
+offset=0.013
+tax.set_custom_ticks(fontsize=8, offset=offset,
+ tick_formats="%.1f", linewidth=0.25)
+```
+
+
+
+
+
+
+Please see the [truncated simplex example](examples/truncated_simplex_example.py)
+for further details.
# RGBA colors
@@ -463,6 +516,7 @@ contribute.
- Bryan Weinstein [btweinstein](https://github.com/btweinstein): Hexagonal heatmaps, colored trajectory plots
- [chebee7i](https://github.com/chebee7i): Docs and figures, triangular heatmapping
- [Cory Simon](https://github.com/CorySimon): Axis Colors, colored heatmap example
+- [tgwoodcock](https://github.com/tgwoodcock): Custom axis data limits, truncated simplex
# Known-Issues
diff --git a/examples/custom_axis_scaling.py b/examples/custom_axis_scaling.py
index 9559c4f..6199b7c 100644
--- a/examples/custom_axis_scaling.py
+++ b/examples/custom_axis_scaling.py
@@ -1,12 +1,24 @@
-import ternary
+"""
+This script gives two examples of setting custom axis data limits instead of
+having the axis limits being from 0 to scale as is the default case.
+
+In the first example we simply set some axis data limits, get and set the
+ticks for the axes and then scatter some data. This example is then repeated
+but with the additional feature of showing custom axis tick formatting.
+
+The second example shows how to use custom axis scaling to achieve a zoom
+effect. We draw the full plot on the left and then zoom into a specific
+region and plot that on the right. The basic principle is the same as the
+first example.
+"""
-# Simple example:
-## Boundary and Gridlines
-scale = 9
-figure, tax = ternary.figure(scale=scale)
+import ternary
+## Simple example:
+figure, tax = ternary.figure(scale=9)
+figure.set_size_inches((4.8,4.8))
+figure.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95)
tax.ax.axis("off")
-figure.set_facecolor('w')
# Draw Boundary and Gridlines
tax.boundary(linewidth=1.0)
@@ -19,10 +31,10 @@
tax.bottom_axis_label("Hogs", fontsize=fontsize, offset=0.06)
-# Set custom axis limits by passing a dict into set_limits.
-# The keys are b, l and r for the three axes and the vals are a list
+# Set custom axis DATA limits by passing a dict into set_axis_limits.
+# The keys are b, l and r for the three axes and the values are a list
# of the min and max in data coords for that axis. max-min for each
-# axis must be the same as the scale i.e. 9 in this case.
+# axis is the same as the scale i.e. 9 in this case.
tax.set_axis_limits({'b': [67, 76], 'l': [24, 33], 'r': [0, 9]})
# get and set the custom ticks:
tax.get_ticks_from_axis_limits()
@@ -35,15 +47,14 @@
tax.ax.set_aspect('equal', adjustable='box')
tax._redraw_labels()
+figure.canvas.draw()
## Simple example with axis tick formatting:
-## Boundary and Gridlines
-scale = 9
-figure, tax = ternary.figure(scale=scale)
-
+figure, tax = ternary.figure(scale=9)
+figure.set_size_inches((4.8,4.8))
+figure.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95)
tax.ax.axis("off")
-figure.set_facecolor('w')
# Draw Boundary and Gridlines
tax.boundary(linewidth=1.0)
@@ -55,33 +66,34 @@
tax.right_axis_label("Dogs", fontsize=fontsize, offset=0.12)
tax.bottom_axis_label("Hogs", fontsize=fontsize, offset=0.06)
-
-# Set custom axis limits by passing a dict into set_limits.
-# The keys are b, l and r for the three axes and the vals are a list
+# Set custom axis DATA limits by passing a dict into set_axis_limits.
+# The keys are b, l and r for the three axes and the values are a list
# of the min and max in data coords for that axis. max-min for each
-# axis must be the same as the scale i.e. 9 in this case.
+# axis is the same as the scale i.e. 9 in this case.
tax.set_axis_limits({'b': [67, 76], 'l': [24, 33], 'r': [0, 9]})
+
# get and set the custom ticks:
# custom tick formats:
# tick_formats can either be a dict, like below or a single format string
# e.g. "%.3e" (valid for all 3 axes) or None, in which case, ints are
# plotted for all 3 axes.
tick_formats = {'b': "%.2f", 'r': "%d", 'l': "%.1f"}
-
tax.get_ticks_from_axis_limits()
tax.set_custom_ticks(fontsize=10, offset=0.02, tick_formats=tick_formats)
# data can be plotted by entering data coords (rather than simplex coords):
points = [(70, 3, 27), (73, 2, 25), (68, 6, 26)]
-points_c = tax.convert_coordinates(points,axisorder='brl')
+points_c = tax.convert_coordinates(points, axisorder='brl')
tax.scatter(points_c, marker='o', s=25, c='r')
tax.ax.set_aspect('equal', adjustable='box')
tax._redraw_labels()
+figure.canvas.draw()
+
## Zoom example:
-## Draw a plot with the full range on the left and a second plot which
-## shows a zoomed region of the left plot.
+# Draw a plot with the full range on the left and a second plot which
+# shows a zoomed region of the left plot.
fig = ternary.plt.figure(figsize=(11, 6))
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)
@@ -114,8 +126,8 @@
tax2.set_axis_limits({'b': [60, 75], 'l': [15, 30], 'r': [10, 25]})
tax2.get_ticks_from_axis_limits(multiple=5)
tick_formats = "%.1f"
-tax2.set_custom_ticks(fontsize=10, offset=0.025, multiple=5,
- axes_colors=axes_colors, tick_formats=tick_formats)
+tax2.set_custom_ticks(fontsize=10, offset=0.025, axes_colors=axes_colors,
+ tick_formats=tick_formats)
# plot some data
points = [(62, 12, 26), (63.5, 13.5, 23), (65, 14, 21), (61, 15, 24),
@@ -132,11 +144,10 @@
tax1.line((60, 10, 30), (60, 25, 15), color='r', lw=2.0)
tax1.line((75, 10, 15), (60, 25, 15), color='r', lw=2.0)
-fig.set_facecolor("w")
-
tax1.ax.set_position([0.01, 0.05, 0.46, 0.8])
tax2.ax.set_position([0.50, 0.05, 0.46, 0.8])
tax1.resize_drawing_canvas()
tax2.resize_drawing_canvas()
+figure.canvas.draw()
ternary.plt.show()
diff --git a/examples/truncated_simplex_example.py b/examples/truncated_simplex_example.py
new file mode 100644
index 0000000..e008deb
--- /dev/null
+++ b/examples/truncated_simplex_example.py
@@ -0,0 +1,139 @@
+"""
+This script gives two examples of truncation i.e. cutting one
+or more corners off the simplex to save whitespace in a figure.
+
+The first example is simple: only the top corner is truncated and the data
+coordainates are the same as the simplex coordinates.
+
+The second example is more complex: all three corners have been truncated
+and we set axis data limits which are not the same as the simplex coords.
+"""
+
+import ternary
+
+## Simple example with the top corner truncated
+scale = 10
+figure, tax = ternary.figure(scale=scale)
+figure.subplots_adjust(left=-0.1, right=1.1, bottom=0.1, top=1.1)
+tax.set_truncation({'rl' : 8})
+tax.ax.axis("off")
+
+
+# Draw Boundary and Gridlines
+tax.boundary(linewidth=0.25)
+tax.gridlines(color="black", multiple=1, linewidth=0.25, ls='-')
+
+
+# Set Axis labels
+tax.left_axis_label(r"$\longleftarrow$ Hogs", fontsize=10)
+tax.right_axis_label(r"$\longleftarrow$ Dogs", fontsize=10)
+tax.bottom_axis_label(r"Logs $\longrightarrow$", fontsize=10, offset=0.08)
+
+
+# As we have set a truncation, we need to get and set custom ticks
+tax.get_ticks_from_axis_limits(multiple=2)
+offset=0.013
+tax.set_custom_ticks(fontsize=8, offset=offset,
+ tick_formats="%.1f", linewidth=0.25)
+# here we have used a tick formatting string to label all the axes with
+# floats to one decimal place.
+
+tax.ax.axis("scaled")
+tax._redraw_labels()
+figure.canvas.draw()
+
+
+
+
+
+
+
+## More complex example with truncations on all 3 corners of the simplex
+## and axes with data coordinates which are different to simplex coordinates.
+scale = 14
+figure, tax = ternary.figure(scale=scale)
+w_i,h_i = 3.15, 2.36
+figure.set_size_inches((w_i,h_i))
+figure.set_dpi(150)
+tax.ax.axis("off")
+figure.subplots_adjust(left=0, right=1, bottom=0, top=1)
+
+# here we set the data limits of the axes (of the complete simplex)
+tax.set_axis_limits({'b' : [52, 59], 'r' : [0, 7], 'l' : [41, 48]})
+
+# now we set the truncation of all 3 corners in data coords. The truncation
+# point refers to the first axis in the key e.g. "b" will be cut off at 57.5
+# parallel to the left axis until we reach the "r" axis for "br" : 57.5
+tax.set_truncation({'br' : 57.5, 'rl' : 4, 'lb' : 46.5})
+
+# Draw Boundary and Gridlines
+tax.boundary(linewidth=0.25)
+tax.gridlines(color="black", multiple=1, linewidth=0.25, ls='-')
+
+# As the truncated figure is no longer a triangle, we need to set custom
+# positions for the axis labels. One way is to enter positions as 2-tuples
+# in xy data coords (e.g. obtained interactively by the hovering the mouse
+# over the matplotlib figure axes) and convert them to simplex coords
+# (3-tuples) for plotting:
+qs = {"l" : (1.94, 5.80),
+ "b" : (6.67, -1.5),
+ "r" : (12.34, 5.58)
+ }
+
+pos = {i : ternary.helpers.planar_to_coordinates(j, tax._scale).tolist()
+ for i, j in qs.items()
+ }
+
+fontsize = 10
+tax.left_axis_label(r"$\longleftarrow$ Hogs", position=pos["l"],
+ fontsize=fontsize)
+tax.right_axis_label(r"$\longleftarrow$ Dogs", position=pos["r"],
+ fontsize=fontsize)
+tax.bottom_axis_label(r"Logs $\longrightarrow$", position=pos["b"],
+ fontsize=fontsize)
+
+
+# We also need to set custom ticks for this example.
+# We could use tax.get_ticks_from_axis_limits(multiple=1) and this gives
+# us all the ticks on the remaining visible parts of the simplex boundary.
+# Instead we show here how to plot specific ticks.
+# define ticks in data coords along each axis:
+tax._ticks = {'b' : [54,55,56,57],
+ 'r' : [2,3,4],
+ 'l' : [44,45,46]}
+# define tick locations along each axis in simplex coords:
+tax._ticklocs = {'b' : [4,6,8,10],
+ 'r' : [4,6,8],
+ 'l' : [4,6,8]}
+
+offset=0.013
+tax.set_custom_ticks(fontsize=8, offset=offset, tick_formats="%i",
+ linewidth=0.25)
+
+# As we have applied a truncation, it can be helpful to plot extra
+# ticks which are not located on the simplex boundary. We specify
+# which axis the tick belongs to so that the tick can be drawn with
+# the correct orientation: horizontal, right parallel or left parallel.
+# Then give the position of the tick in simplex coordinates and specify
+# the tick label as a string in data coordinates:
+tax.add_extra_tick('r', (11,2,1), offset, '1', fontsize=8, color='k',
+ linewidth=0.25)
+tax.add_extra_tick('r', (11,0,3), offset, '0', fontsize=8, color='k',
+ linewidth=0.25)
+
+tax.add_extra_tick('l', (2,8,4), offset, '43', fontsize=8, color='k',
+ linewidth=0.25)
+tax.add_extra_tick('l', (4,8,2), offset, '42', fontsize=8, color='k',
+ linewidth=0.25)
+tax.add_extra_tick('l', (6,8,0), offset, '41', fontsize=8, color='k',
+ linewidth=0.25)
+
+tax.add_extra_tick('b', (2,1,11), offset, '53', fontsize=8, color='k',
+ linewidth=0.25)
+
+
+tax.ax.axis("scaled")
+tax.ax.axis([0, 14, -2, 9])
+tax._redraw_labels()
+
+ternary.plt.show()
diff --git a/readme_images/truncation_all_corners.png b/readme_images/truncation_all_corners.png
new file mode 100644
index 0000000..1d509b8
Binary files /dev/null and b/readme_images/truncation_all_corners.png differ
diff --git a/readme_images/truncation_top_corner.png b/readme_images/truncation_top_corner.png
new file mode 100644
index 0000000..841e215
Binary files /dev/null and b/readme_images/truncation_top_corner.png differ
diff --git a/readme_images/zoom_example.png b/readme_images/zoom_example.png
new file mode 100644
index 0000000..089e3cb
Binary files /dev/null and b/readme_images/zoom_example.png differ
diff --git a/ternary/colormapping.py b/ternary/colormapping.py
index c264463..6c1fe6f 100644
--- a/ternary/colormapping.py
+++ b/ternary/colormapping.py
@@ -91,7 +91,7 @@ def colorbar_hack(ax, vmin, vmax, cmap, scientific=False, cbarlabel=None, norm=N
if norm is None:
norm = plt.Normalize(vmin=vmin, vmax=vmax)
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
- sm._A = []
+ sm.set_array(None)
cb = plt.colorbar(sm, ax=ax, **kwargs)
if cbarlabel is not None:
cb.set_label(cbarlabel)
diff --git a/ternary/heatmapping.py b/ternary/heatmapping.py
index 7487f69..63d051d 100644
--- a/ternary/heatmapping.py
+++ b/ternary/heatmapping.py
@@ -318,7 +318,7 @@ def heatmapf(func, scale=10, boundary=True, cmap=None, ax=None,
# Pass everything to the heatmapper
ax = heatmap(data, scale, cmap=cmap, ax=ax, style=style,
scientific=scientific, colorbar=colorbar,
- permutation=permutation, vmin=vmin, vmax=vmax,
+ permutation=permutation, vmin=vmin, vmax=vmax,
cbarlabel=cbarlabel, cb_kwargs=cb_kwargs)
return ax
@@ -411,9 +411,20 @@ def svg_heatmap(data, scale, filename, vmax=None, vmin=None, style='h',
output_file.write('\n')
-def background_color(ax, color, scale, zorder=-1000, alpha=None):
+def background_color(ax, color, scale, axis_min_max, zorder=-1000, alpha=None):
"""Draws a triangle behind the plot to serve as the background color."""
- vertices = [(scale, 0, 0), (0, scale, 0), (0, 0, scale)]
+ vertices = [(axis_min_max["b"][1], 0, scale - axis_min_max["b"][1]),
+ (axis_min_max["b"][1], axis_min_max["r"][0], 0),
+ (scale - axis_min_max["r"][1], axis_min_max["r"][1], 0),
+ (0, axis_min_max["r"][1], axis_min_max["l"][0]),
+ (0, scale - axis_min_max["l"][1], axis_min_max["l"][1]),
+ (axis_min_max["b"][0], 0, axis_min_max["l"][1])
+ ]
+
+ _, idx = np.unique(vertices, return_index=True, axis=0)
+ idx.sort()
+ vertices = [vertices[i] for i in idx]
+
vertices = map(project_point, vertices)
xs, ys = unzip(vertices)
poly = ax.fill(xs, ys, facecolor=color, edgecolor=color, zorder=zorder, alpha=alpha)
diff --git a/ternary/helpers.py b/ternary/helpers.py
index 660c046..f6afd54 100644
--- a/ternary/helpers.py
+++ b/ternary/helpers.py
@@ -112,7 +112,7 @@ def planar_to_coordinates(p, scale):
----------
p: 2-tuple
The planar simplex (x, y) point to be transformed to maps (x,y,z) coordinates
-
+
scale: Int
The normalized scale of the simplex, i.e. N such that points (x,y,z)
satisfy x + y + z == N
@@ -122,8 +122,8 @@ def planar_to_coordinates(p, scale):
x = p[0] - y / 2.
z = scale - x - y
return np.array([x, y, z])
-
-
+
+
def project_sequence(s, permutation=None):
"""
Projects a point or sequence of points using `project_point` to lists xs, ys
@@ -136,7 +136,7 @@ def project_sequence(s, permutation=None):
Returns
-------
- xs, ys: The sequence of projected points in coordinates as two lists
+ xs, ys: The sequence of projected points in coordinates as two lists
"""
xs, ys = unzip([project_point(p, permutation=permutation) for p in s])
@@ -147,7 +147,7 @@ def project_sequence(s, permutation=None):
def convert_coordinates(q, conversion, axisorder):
"""
- Convert a 3-tuple in data coordinates into to simplex data
+ Convert a 3-tuple in data coordinates to simplex
coordinates for plotting.
Parameters
@@ -188,7 +188,7 @@ def get_conversion(scale, limits):
"r": lambda x: (x - limits['r'][0]) * fr}
return conversion
-
+
def convert_coordinates_sequence(qs, scale, limits, axisorder):
"""
@@ -216,5 +216,5 @@ def convert_coordinates_sequence(qs, scale, limits, axisorder):
the points converted to simplex coordinates
"""
conversion = get_conversion(scale, limits)
-
+
return [convert_coordinates(q, conversion, axisorder) for q in qs]
diff --git a/ternary/lines.py b/ternary/lines.py
index 436798c..e495538 100644
--- a/ternary/lines.py
+++ b/ternary/lines.py
@@ -31,7 +31,7 @@ def line(ax, p1, p2, permutation=None, **kwargs):
ax.add_line(Line2D((pp1[0], pp2[0]), (pp1[1], pp2[1]), **kwargs))
-def horizontal_line(ax, scale, i, **kwargs):
+def horizontal_line(ax, scale, i, axis_min_max, **kwargs):
"""
Draws the i-th horizontal line parallel to the lower axis.
@@ -43,16 +43,32 @@ def horizontal_line(ax, scale, i, **kwargs):
Simplex scale size.
i: float
The index of the line to draw
+ axis_min_max: dict
+ The min and max values of the axes in simplex coordinates.
+ These may not be equal to (0, scale) if a truncation has been
+ applied.
kwargs: Dictionary
Any kwargs to pass through to Matplotlib.
"""
+ if i <= axis_min_max['r'][1]:
+ if i < scale-axis_min_max['l'][1]:
+ p1 = (axis_min_max['b'][0] - i,
+ i,
+ axis_min_max['l'][1])
+ else:
+ p1 = (0, i, scale-i)
- p1 = (0, i, scale - i)
- p2 = (scale - i, i, 0)
- line(ax, p1, p2, **kwargs)
+ if i < axis_min_max['r'][0]:
+ p2 = (axis_min_max['b'][1],
+ i,
+ scale - axis_min_max['b'][1] - i)
+ else:
+ p2 = (scale - i, i, 0)
+ line(ax, p1, p2, **kwargs)
-def left_parallel_line(ax, scale, i, **kwargs):
+
+def left_parallel_line(ax, scale, i, axis_min_max, **kwargs):
"""
Draws the i-th line parallel to the left axis.
@@ -64,16 +80,32 @@ def left_parallel_line(ax, scale, i, **kwargs):
Simplex scale size.
i: float
The index of the line to draw
+ axis_min_max: dict
+ The min and max values of the axes in simplex coordinates.
+ These may not be equal to (0, scale) if a truncation has been
+ applied.
kwargs: Dictionary
Any kwargs to pass through to Matplotlib.
"""
+ if i <= axis_min_max['b'][1]:
+ if i < scale-axis_min_max['r'][1]:
+ p1 = (i,
+ axis_min_max['r'][1],
+ axis_min_max['l'][0] - i)
+ else:
+ p1 = (i, scale - i, 0)
+
+ if i < axis_min_max['b'][0]:
+ p2 = (i,
+ scale - axis_min_max['l'][1] - i,
+ axis_min_max['l'][1])
+ else:
+ p2 = (i, 0, scale - i)
- p1 = (i, scale - i, 0)
- p2 = (i, 0, scale - i)
- line(ax, p1, p2, **kwargs)
+ line(ax, p1, p2, **kwargs)
-def right_parallel_line(ax, scale, i, **kwargs):
+def right_parallel_line(ax, scale, i, axis_min_max=None, **kwargs):
"""
Draws the i-th line parallel to the right axis.
@@ -85,18 +117,34 @@ def right_parallel_line(ax, scale, i, **kwargs):
Simplex scale size.
i: float
The index of the line to draw
+ axis_min_max: dict
+ The min and max values of the axes in simplex coordinates.
+ These may not be equal to (0, scale) if a truncation has been
+ applied.
kwargs: Dictionary
Any kwargs to pass through to Matplotlib.
"""
+ if i <= axis_min_max['l'][1]:
+ if i < axis_min_max['l'][0]:
+ p1 = (scale - axis_min_max['r'][1] - i,
+ axis_min_max['r'][1],
+ i)
+ else:
+ p1 = (0, scale - i, i)
+
+ if i < scale - axis_min_max['b'][1]:
+ p2 = (axis_min_max['b'][1],
+ scale - axis_min_max['b'][1] - i,
+ i)
+ else:
+ p2 = (scale - i, 0, i)
- p1 = (0, scale - i, i)
- p2 = (scale - i, 0, i)
- line(ax, p1, p2, **kwargs)
+ line(ax, p1, p2, **kwargs)
## Boundary, Gridlines ##
-def boundary(ax, scale, axes_colors=None, **kwargs):
+def boundary(ax, scale, axis_min_max, axes_colors=None, **kwargs):
"""
Plots the boundary of the simplex. Creates and returns matplotlib axis if
none given.
@@ -107,23 +155,45 @@ def boundary(ax, scale, axes_colors=None, **kwargs):
The subplot to draw on.
scale: float
Simplex scale size.
- kwargs:
- Any kwargs to pass through to matplotlib.
+ axis_min_max: dict
+ The min and max values of the axes in simplex coordinates.
+ These may not be equal to (0, scale) if a truncation has been
+ applied.
axes_colors: dict
Option for coloring boundaries different colors.
e.g. {'l': 'g'} for coloring the left axis boundary green
+ kwargs:
+ Any kwargs to pass through to matplotlib.
"""
- # Set default color as black.
+ # set default color as black
if axes_colors is None:
axes_colors = dict()
for _axis in ['l', 'r', 'b']:
if _axis not in axes_colors.keys():
axes_colors[_axis] = 'black'
- horizontal_line(ax, scale, 0, color=axes_colors['b'], **kwargs)
- left_parallel_line(ax, scale, 0, color=axes_colors['l'], **kwargs)
- right_parallel_line(ax, scale, 0, color=axes_colors['r'], **kwargs)
+ horizontal_line(ax, scale, 0, axis_min_max,
+ color=axes_colors['b'], **kwargs)
+ left_parallel_line(ax, scale, 0, axis_min_max,
+ color=axes_colors['l'], **kwargs)
+ right_parallel_line(ax, scale, 0, axis_min_max,
+ color=axes_colors['r'], **kwargs)
+
+ if axis_min_max['r'][1] < scale:
+ horizontal_line(ax, scale, axis_min_max['r'][1],
+ axis_min_max=axis_min_max,
+ color=axes_colors['r'], **kwargs)
+ if axis_min_max['b'][1] < scale:
+ left_parallel_line(ax, scale, axis_min_max['b'][1],
+ axis_min_max=axis_min_max,
+ color=axes_colors['b'], **kwargs)
+ if axis_min_max['l'][1] < scale:
+ right_parallel_line(ax, scale, axis_min_max['l'][1],
+ axis_min_max=axis_min_max,
+ color=axes_colors['l'], **kwargs)
+
+
return ax
@@ -147,8 +217,9 @@ def merge_dicts(base, updates):
return z
-def gridlines(ax, scale, multiple=None, horizontal_kwargs=None,
- left_kwargs=None, right_kwargs=None, **kwargs):
+def gridlines(ax, scale, axis_min_max, multiple=None,
+ horizontal_kwargs=None, left_kwargs=None, right_kwargs=None,
+ **kwargs):
"""
Plots grid lines excluding boundary.
@@ -158,8 +229,12 @@ def gridlines(ax, scale, multiple=None, horizontal_kwargs=None,
The subplot to draw on.
scale: float
Simplex scale size.
+ axis_min_max: dict
+ The min and max values of the axes in simplex coordinates.
+ These may not be equal to (0, scale) if a truncation has been
+ applied.
multiple: float, None
- Specifies which inner gridelines to draw. For example, if scale=30 and
+ Specifies which inner gridlines to draw. For example, if scale=30 and
multiple=6, only 5 inner gridlines will be drawn.
horizontal_kwargs: dict, None
Any kwargs to pass through to matplotlib for horizontal gridlines
@@ -184,11 +259,12 @@ def gridlines(ax, scale, multiple=None, horizontal_kwargs=None,
## Draw grid-lines
# Parallel to horizontal axis
for i in arange(0, scale, multiple):
- horizontal_line(ax, scale, i, **horizontal_kwargs)
+ horizontal_line(ax, scale, i, axis_min_max, **horizontal_kwargs)
# Parallel to left and right axes
for i in arange(0, scale + multiple, multiple):
- left_parallel_line(ax, scale, i, **left_kwargs)
- right_parallel_line(ax, scale, i, **right_kwargs)
+ left_parallel_line(ax, scale, i, axis_min_max, **left_kwargs)
+ right_parallel_line(ax, scale, i, axis_min_max, **right_kwargs)
+
return ax
@@ -222,7 +298,7 @@ def ticks(ax, scale, ticks=None, locations=None, multiple=1, axis='b',
locations: list of points, None
The locations of the ticks
multiple: float, None
- Specifies which ticks gridelines to draw. For example, if scale=30 and
+ Specifies which ticks to draw. For example, if scale=30 and
multiple=6, only 5 ticks will be drawn.
axis: str, 'b'
The axis or axes to draw the ticks for. `axis` must be a substring of
@@ -337,3 +413,59 @@ def ticks(ax, scale, ticks=None, locations=None, multiple=1, axis='b',
s = tick_formats['b'] % tick
ax.text(x, y, s, horizontalalignment="center",
color=axes_colors['b'], fontsize=fontsize)
+
+
+def add_extra_tick(ax, axis, loc1, offset, scale, tick, fontsize, **kwargs):
+ """
+ Add an extra tick on an axis but not necessarily on
+ the boundary of the simplex. This may be useful if a truncation is applied.
+
+ Parameters
+ ----------
+ ax : matplotlib.Axes
+ The matplotlib Axes object containing the plot.
+ axis : STR
+ A string giving the axis on which the extra tick should be drawn.
+ One of 'l', 'b' or 'r'.
+ loc1 : 3-tuple
+ A 3-tuple giving the location of the extra tick in simplex coords.
+ offset : FLOAT
+ Defines an offset of the tick label and the length of the tick
+ scale : INT
+ The self._scale attibute of the simplex
+ tick : STR
+ A string giving the text for the tick label
+ fontsize : INT
+ Describing the font size of the tick label
+ **kwargs : DICT
+ Kwargs to pass through to matplotlib Line2D.
+
+ Returns
+ -------
+ None.
+
+ """
+ toff = offset * scale
+
+ if axis == 'r':
+ loc2 = (loc1[0] + toff, loc1[1], loc1[2]-toff)
+ text_location = (loc1[0] + 2.6 * toff,
+ loc1[1] - 0.5 * toff,
+ loc1[2] - 2.6 * toff)
+
+ elif axis == 'l':
+ loc2 = (loc1[0] - toff, loc1[1] + toff, loc1[2])
+ text_location = (loc1[0] - 2 * toff,
+ loc1[1] + 1.5 * toff,
+ loc1[2] + 2 * toff)
+
+ elif axis == 'b':
+ loc2 = (loc1[0], loc1[1] - toff, loc1[2] + toff)
+ text_location = (loc1[0] - 0.5 * toff,
+ loc1[1] - 3.5 * toff,
+ loc1[2] + 2 * toff)
+
+
+ line(ax, loc1, loc2, **kwargs)
+ x, y = project_point(text_location)
+ ax.text(x,y,tick,horizontalalignment='center',fontsize=fontsize)
diff --git a/ternary/ternary_axes_subplot.py b/ternary/ternary_axes_subplot.py
index dd56f9b..488ea30 100644
--- a/ternary/ternary_axes_subplot.py
+++ b/ternary/ternary_axes_subplot.py
@@ -71,6 +71,18 @@ def __init__(self, ax=None, scale=None, permutation=None):
self._labels = dict()
self._corner_labels = dict()
self._ticks = dict()
+ self._ticklocs = dict()
+ # Container for data limits for the axes. Custom limits can
+ # be set by the user
+ self.set_axis_limits({"b" : [0, self._scale],
+ "r" : [0, self._scale],
+ "l" : [0, self._scale]})
+
+ # Container for parameters describing a possible truncation
+ self._truncation = dict()
+ self._axis_min_max = {"b" : [0, self._scale],
+ "r" : [0, self._scale],
+ "l" : [0, self._scale]}
# Container for the redrawing of labels
self._to_remove = []
self._connect_callbacks()
@@ -119,8 +131,80 @@ def set_axis_limits(self, axis_limits=None):
self._axis_limits = axis_limits
def get_axis_limits(self):
+ """Get the data limits for each axis"""
return self._axis_limits
+ def set_axis_min_max(self, truncation):
+ """
+ Set the min and max values of the axes in SIMPLEX coords
+ (rather than data coords) given various
+ truncation points.
+
+ !! Assumes the truncation lines do NOT cross each other!!
+
+ truncation: dict
+ keys are 'br', 'rl' and/or 'lb'
+ values are a value in SIMPLEX coords giving the maximum of the
+ first axis mentioned in the key
+ """
+ for k in truncation.keys():
+ self._axis_min_max[k[0]][1] = truncation[k]
+ self._axis_min_max[k[1]][0] = self._scale - truncation[k]
+
+
+ def get_axis_min_max(self):
+ """Get the simplex limits for each axis"""
+ return self._axis_min_max
+
+
+ def set_truncation(self, truncation_data):
+ """
+ Set one or more truncation lines which will be used to truncate
+ the simplex i.e. cut one or more corners off to remove whitespace.
+
+ The self.axis_limits (data limits) and self.axis_min_max (simplex
+ limits) are set by this function.
+
+ Truncation lines may not cross each other!
+
+ Parameters
+ ----------
+ truncation_data : dict
+ keys are 'br', 'rl' and/or 'lb'
+ values are a value in DATA coords giving the maximum of the
+ first axis mentioned in the key. These are then transformed
+ into SIMPLEX coords and stored internally.
+
+ Returns
+ -------
+ None.
+
+ """
+ steps = {i : (j[1] - j[0]) / float(self._scale) for i, j in
+ self._axis_limits.items()}
+
+ axlim = {i : j[:] for i, j in self._axis_limits.items()}
+
+ for k in truncation_data:
+
+ self._truncation[k] = int((truncation_data[k]-
+ axlim[k[0]][0])/steps[k[0]])
+
+ self._axis_limits[k[0]][1] = truncation_data[k]
+
+ self._axis_limits[k[1]][0] = axlim[k[1]][0] + steps[k[1]] *\
+ (self._scale - self._truncation[k])
+
+ self.set_axis_min_max(self._truncation)
+ self._draw_background()
+
+
+ def get_truncation(self):
+ """
+ This returns the truncation in SIMPLEX coords
+ """
+ return self._truncation
+
# Title and Axis Labels
def set_title(self, title, **kwargs):
@@ -128,8 +212,8 @@ def set_title(self, title, **kwargs):
ax = self.get_axes()
ax.set_title(title, **kwargs)
- def left_axis_label(self, label, position=None, rotation=60, offset=0.08,
- **kwargs):
+ def left_axis_label(self, label, position=None, rotation=60, offset=0.08,
+ transform_type="transData", **kwargs):
"""
Sets the label on the left axis.
@@ -149,10 +233,12 @@ def left_axis_label(self, label, position=None, rotation=60, offset=0.08,
if not position:
position = (-offset, 3./5, 2./5)
- self._labels["left"] = (label, position, rotation, kwargs)
+ transform_type = "transAxes"
+ self._labels["left"] = (label, position, rotation,
+ transform_type, kwargs)
def right_axis_label(self, label, position=None, rotation=-60, offset=0.08,
- **kwargs):
+ transform_type="transData", **kwargs):
"""
Sets the label on the right axis.
@@ -173,10 +259,12 @@ def right_axis_label(self, label, position=None, rotation=-60, offset=0.08,
if not position:
position = (2. / 5 + offset, 3. / 5, 0)
- self._labels["right"] = (label, position, rotation, kwargs)
+ transform_type = "transAxes"
+ self._labels["right"] = (label, position, rotation,
+ transform_type, kwargs)
def bottom_axis_label(self, label, position=None, rotation=0, offset=0.02,
- **kwargs):
+ transform_type="transData", **kwargs):
"""
Sets the label on the bottom axis.
@@ -196,10 +284,12 @@ def bottom_axis_label(self, label, position=None, rotation=0, offset=0.02,
if not position:
position = (0.5, -offset / 2., 0.5)
- self._labels["bottom"] = (label, position, rotation, kwargs)
+ transform_type = "transAxes"
+ self._labels["bottom"] = (label, position, rotation,
+ transform_type, kwargs)
def right_corner_label(self, label, position=None, rotation=0, offset=0.08,
- **kwargs):
+ transform_type="transData", **kwargs):
"""
Sets the label on the right corner (complements left axis).
@@ -219,10 +309,12 @@ def right_corner_label(self, label, position=None, rotation=0, offset=0.08,
if not position:
position = (1, offset / 2, 0)
- self._corner_labels["right"] = (label, position, rotation, kwargs)
+ transform_type = "transAxes"
+ self._corner_labels["right"] = (label, position, rotation,
+ transform_type, kwargs)
def left_corner_label(self, label, position=None, rotation=0, offset=0.08,
- **kwargs):
+ transform_type="transData", **kwargs):
"""
Sets the label on the left corner (complements right axis.)
@@ -242,10 +334,12 @@ def left_corner_label(self, label, position=None, rotation=0, offset=0.08,
if not position:
position = (-offset / 2, offset / 2, 0)
- self._corner_labels["left"] = (label, position, rotation, kwargs)
+ transform_type="transAxes"
+ self._corner_labels["left"] = (label, position, rotation,
+ transform_type, kwargs)
def top_corner_label(self, label, position=None, rotation=0, offset=0.2,
- **kwargs):
+ transform_type="transData", **kwargs):
"""
Sets the label on the bottom axis.
@@ -265,7 +359,9 @@ def top_corner_label(self, label, position=None, rotation=0, offset=0.2,
if not position:
position = (-offset / 2, 1 + offset, 0)
- self._corner_labels["top"] = (label, position, rotation, kwargs)
+ transform_type="transAxes"
+ self._corner_labels["top"] = (label, position, rotation,
+ transform_type, kwargs)
def annotate(self, text, position, **kwargs):
ax = self.get_axes()
@@ -275,27 +371,80 @@ def annotate(self, text, position, **kwargs):
# Boundary and Gridlines
def boundary(self, scale=None, axes_colors=None, **kwargs):
+ """
+ Draw a boundary around the simplex.
+
+ Parameters
+ ----------
+ scale : INT, optional
+ An int describing the scale of the boundary to be drawn.
+ Sometimes you may want to draw a bigger boundary than
+ specified in the initialisation of the tax. The default is None.
+ axes_colors: dict
+ Option for coloring boundaries different colors.
+ e.g. {'l': 'g'} for coloring the left axis boundary green
+ **kwargs : dict
+ Any kwargs to pass through to matplotlib..
+
+ Returns
+ -------
+ None.
+
+ """
# Sometimes you want to draw a bigger boundary
if not scale:
- scale = self._boundary_scale # defaults to self._scale
+ scale = self._boundary_scale # defaults to self._scale
ax = self.get_axes()
self.resize_drawing_canvas(scale)
- lines.boundary(scale=scale, ax=ax, axes_colors=axes_colors, **kwargs)
- def gridlines(self, multiple=None, horizontal_kwargs=None, left_kwargs=None,
- right_kwargs=None, **kwargs):
+ lines.boundary(ax, scale, self._axis_min_max,
+ axes_colors=axes_colors, **kwargs)
+
+
+ def gridlines(self, multiple=None, horizontal_kwargs=None,
+ left_kwargs=None, right_kwargs=None, **kwargs):
+ """
+ Draw gridlines on the simplex (excluding the boundary).
+
+ Parameters
+ ----------
+ multiple: int, optional
+ Specifies which inner gridelines to draw. For example,
+ if scale=30 and multiple=6, only 5 inner gridlines will be drawn.
+ The default is None.
+ horizontal_kwargs: dict, optional
+ Any kwargs to pass through to matplotlib for horizontal gridlines
+ The default is None.
+ left_kwargs: dict, optional
+ Any kwargs to pass through to matplotlib for left parallel gridlines
+ right_kwargs: dict, optional
+ Any kwargs to pass through to matplotlib for right parallel gridlines
+ The default is None.
+ kwargs:
+ Any kwargs to pass through to matplotlib, if not using
+ horizontal_kwargs, left_kwargs, or right_kwargs
+
+ Returns
+ -------
+ None.
+
+ """
ax = self.get_axes()
scale = self.get_scale()
- lines.gridlines(scale=scale, multiple=multiple,
- ax=ax, horizontal_kwargs=horizontal_kwargs,
- left_kwargs=left_kwargs, right_kwargs=right_kwargs,
+
+ lines.gridlines(ax, scale, self._axis_min_max,
+ multiple=multiple,
+ horizontal_kwargs=horizontal_kwargs,
+ left_kwargs=left_kwargs,
+ right_kwargs=right_kwargs,
**kwargs)
# Various Lines
def line(self, p1, p2, **kwargs):
ax = self.get_axes()
- lines.line(ax, p1, p2, **kwargs)
+ permutation = self._permutation
+ lines.line(ax, p1, p2, permutation=permutation, **kwargs)
def horizontal_line(self, i, **kwargs):
ax = self.get_axes()
@@ -340,33 +489,129 @@ def clear_matplotlib_ticks(self, axis="both"):
ax = self.get_axes()
plotting.clear_matplotlib_ticks(ax=ax, axis=axis)
+
def get_ticks_from_axis_limits(self, multiple=1):
"""
- Taking self._axis_limits and self._boundary_scale get the scaled
+ Taking self._axis_limits, self.axis_min_max and self._scale get the
ticks for all three axes and store them in self._ticks under the
- keys 'b' for bottom, 'l' for left and 'r' for right axes.
+ keys 'b' for bottom, 'l' for left and 'r' for right axes. Get the
+ locations of the tickes and store them under self._ticklocs with the
+ same keys.
+
+ NB. the tick locations for the left axis have to be shifted if there
+ is a truncation of that axis, otherwise they are projected in the
+ wrong place by lines.line(), which calls helpers.project_point().
+ This is handled in the last 3 lines of this function.
"""
- for k in ['b', 'l', 'r']:
- self._ticks[k] = np.linspace(
- self._axis_limits[k][0],
- self._axis_limits[k][1],
- int(self._boundary_scale / float(multiple) + 1)
- ).tolist()
+ for k in ['b','l','r']:
+ gg = self._axis_min_max[k][1] - self._axis_min_max[k][0]
+ ff = self._axis_limits[k][1] - self._axis_limits[k][0]
+ step = ff/gg
- def set_custom_ticks(self, locations=None, clockwise=False, multiple=1,
- axes_colors=None, tick_formats=None, **kwargs):
+ self._ticklocs[k] = np.arange(self._axis_min_max[k][0],
+ self._axis_min_max[k][1] + step,
+ multiple).astype("int").tolist()
+
+ self._ticks[k] = np.arange(self._axis_limits[k][0],
+ self._axis_limits[k][1] + step,
+ step*multiple).tolist()
+
+
+ self._ticklocs['l'] = [i - self._axis_min_max["l"][0] +
+ (self._scale - self._axis_min_max["l"][1])
+ for i in self._ticklocs['l']]
+
+
+
+ def set_custom_ticks(self, clockwise=False, axes_colors=None,
+ tick_formats=None, **kwargs):
"""
- Having called get_ticks_from_axis_limits, set the custom ticks on the
- plot.
+ Having called get_ticks_from_axis_limits(), draw the custom ticks on
+ the plot. We call self.ticks() for each axis in turn with the ticks
+ and ticklocs already defined using get_ticks_from_axis_limits().
+
+ Parameters
+ ----------
+ clockwise : BOOL, optional
+ Whether the axes of the simplex run clockwise or not.
+ The default is False.
+ axes_colors: Dict, optional
+ Option to color ticks differently for each axis, 'l', 'r', 'b'
+ e.g. {'l': 'g', 'r':'b', 'b': 'y'}
+ The default is None.
+ tick_formats: None, Dict, Str, optional
+ If None, all axes will be labelled with ints.
+ If Dict, the keys are 'b', 'l' and 'r' and the values are
+ format strings e.g. "%.3f" for a float with 3 decimal places
+ or "%.3e" for scientific format with 3 decimal places or
+ "%d" for ints.
+ If tick_formats is a string, it is assumed that this is a
+ format string to be applied to all axes.
+ The default is None
+ kwargs:
+ Any kwargs to pass through to matplotlib.
+
+ Returns
+ -------
+ None.
+
"""
- for k in ['b', 'l', 'r']:
- self.ticks(ticks=self._ticks[k], locations=locations,
- axis=k, clockwise=clockwise, multiple=multiple,
- axes_colors=axes_colors, tick_formats=tick_formats,
- **kwargs)
+ for k in ['b','l','r']:
+ self.ticks(ticks=self._ticks[k], locations=self._ticklocs[k],
+ axis=k, clockwise=clockwise, axes_colors=axes_colors,
+ tick_formats=tick_formats, **kwargs)
+
def ticks(self, ticks=None, locations=None, multiple=1, axis='blr',
clockwise=False, axes_colors=None, tick_formats=None, **kwargs):
+ """
+ Convenience function passthrough to lines.ticks.
+
+ Calling this function with all the default arguments results in
+ each axis of the simplex being labelled on every gridline with
+ an int. This is the simplest case where the axis_limits (data)
+ have not been set and are therefore the same as the axis_min_max
+ (simplex) limits.
+
+ If set_axis_limits() or set_truncation() has been called, this
+ function should not be used. Instead call get_ticks_from_axis_limits()
+ and then set_custom_ticks().
+
+
+ Parameters
+ ----------
+ ticks: list of strings, None
+ The tick labels
+ locations: list of points, None
+ The locations of the ticks
+ multiple: float, None
+ Specifies which ticks to draw. For example,
+ if scale=30 and multiple=6, only 5 ticks will be drawn.
+ axis: str, 'b'
+ The axis or axes to draw the ticks for. `axis` must be a
+ substring of 'lrb' (as sets)
+ offset: float, 0.01
+ controls the length of the ticks
+ clockwise: bool, False
+ Draw ticks marks clockwise or counterclockwise
+ axes_colors: Dict, None
+ Option to color ticks differently for each axis, 'l', 'r', 'b'
+ e.g. {'l': 'g', 'r':'b', 'b': 'y'}
+ tick_formats: None, Dict, Str
+ If None, all axes will be labelled with ints. If Dict, the keys
+ are 'b', 'l' and 'r' and the values are format strings
+ e.g. "%.3f" for a float with 3 decimal places or "%.3e" for
+ scientific format with 3 decimal places or "%d" for ints.
+ If tick_formats is a string, it
+ is assumed that this is a format string to be applied to all axes.
+ kwargs:
+ Any kwargs to pass through to matplotlib.
+
+ Returns
+ -------
+ None.
+
+ """
ax = self.get_axes()
scale = self.get_scale()
lines.ticks(ax, scale, ticks=ticks, locations=locations,
@@ -374,6 +619,40 @@ def ticks(self, ticks=None, locations=None, multiple=1, axis='blr',
axes_colors=axes_colors, tick_formats=tick_formats,
**kwargs)
+
+ def add_extra_tick(self, axis, loc1, offset, tick, fontsize, **kwargs):
+ """
+ Convenience function passthrough to lines.add_extra_tick.
+
+ Add an extra tick on an axis but not necessarily on
+ the boundary of the simplex. This may be useful if a
+ truncation is applied.
+
+ Parameters
+ ----------
+ axis : STR
+ A string giving the axis on which the extra tick should be drawn.
+ One of 'l', 'b' or 'r'.
+ loc1 : 3-tuple
+ A 3-tuple giving the location of the extra tick in simplex coords.
+ offset : FLOAT
+ Defines an offset of the tick label and the length of the tick
+ tick : STR
+ A string giving the text for the tick label
+ fontsize : INT
+ Describing the font size of the tick label
+ **kwargs : DICT
+ Kwargs to pass through to matplotlib Line2D.
+
+ Returns
+ -------
+ None.
+
+ """
+ lines.add_extra_tick(self.get_axes(), axis, loc1, offset,
+ self.get_scale(), tick, fontsize, **kwargs)
+
+
# Redrawing and resizing
def resize_drawing_canvas(self, scale=None):
@@ -382,8 +661,11 @@ def resize_drawing_canvas(self, scale=None):
scale = self.get_scale()
plotting.resize_drawing_canvas(ax, scale=scale)
+
def _redraw_labels(self):
- """Redraw axis labels, typically after draw or resize events."""
+ """
+ Redraw axis labels, typically after draw or resize events.
+ """
ax = self.get_axes()
# Remove any previous labels
for mpl_object in self._to_remove:
@@ -392,25 +674,30 @@ def _redraw_labels(self):
# Redraw the labels with the appropriate angles
label_data = list(self._labels.values())
label_data.extend(self._corner_labels.values())
- for (label, position, rotation, kwargs) in label_data:
- transform = ax.transAxes
+ for (label, position, rotation, transform_type, kwargs) in label_data:
+ if transform_type == "transAxes":
+ transform = ax.transAxes
+ elif transform_type == "transData":
+ transform = ax.transData
+
x, y = project_point(position)
# Calculate the new angle.
position = np.array([x, y])
- new_rotation = ax.transData.transform_angles(
- np.array((rotation,)), position.reshape((1, 2)))[0]
+ new_rotation = ax.transData.transform_angles(np.array((rotation,)),
+ position.reshape((1, 2)))[0]
text = ax.text(x, y, label, rotation=new_rotation,
transform=transform, horizontalalignment="center",
**kwargs)
text.set_rotation_mode("anchor")
self._to_remove.append(text)
+
def convert_coordinates(self, points, axisorder='blr'):
"""
Convert data coordinates to simplex coordinates for plotting
in the case that axis limits have been applied.
"""
- return convert_coordinates_sequence(points,self._boundary_scale,
+ return convert_coordinates_sequence(points, self._boundary_scale,
self._axis_limits, axisorder)
# Various Plots
@@ -422,18 +709,21 @@ def scatter(self, points, **kwargs):
**kwargs)
return plot_
+
def plot(self, points, **kwargs):
ax = self.get_axes()
permutation = self._permutation
plotting.plot(points, ax=ax, permutation=permutation,
**kwargs)
+
def plot_colored_trajectory(self, points, cmap=None, **kwargs):
ax = self.get_axes()
permutation = self._permutation
plotting.plot_colored_trajectory(points, cmap=cmap, ax=ax,
permutation=permutation, **kwargs)
+
def heatmap(self, data, scale=None, cmap=None, scientific=False,
style='triangular', colorbar=True, use_rgba=False,
vmin=None, vmax=None, cbarlabel=None, cb_kwargs=None):
@@ -449,6 +739,7 @@ def heatmap(self, data, scale=None, cmap=None, scientific=False,
vmin=vmin, vmax=vmax, cbarlabel=cbarlabel,
cb_kwargs=cb_kwargs)
+
def heatmapf(self, func, scale=None, cmap=None, boundary=True,
style='triangular', colorbar=True, scientific=False,
vmin=None, vmax=None, cbarlabel=None, cb_kwargs=None):
@@ -464,18 +755,24 @@ def heatmapf(self, func, scale=None, cmap=None, boundary=True,
vmin=vmin, vmax=vmax, cbarlabel=cbarlabel,
cb_kwargs=cb_kwargs)
+
def set_background_color(self, color="whitesmoke", zorder=-1000, alpha=0.75):
self._background_parameters = BackgroundParameters(color=color, alpha=alpha, zorder=zorder)
self._draw_background()
+
def _draw_background(self):
color, alpha, zorder = self._background_parameters
scale = self.get_scale()
ax = self.get_axes()
+ axis_min_max = self.get_axis_min_max()
# Remove any existing background
if self._background_triangle:
self._background_triangle.remove()
# Draw the background
- self._background_triangle = heatmapping.background_color(ax, color, scale, alpha=alpha, zorder=zorder)[0]
+ self._background_triangle = heatmapping.background_color(ax, color, scale,
+ axis_min_max,
+ alpha=alpha,
+ zorder=zorder)[0]