# Source code for mpl_toolkits.mplot3d.axis3d

# axis3d.py, original mplot3d version by John Porter
# Created: 23 Sep 2005
# Parts rewritten by Reinier Heeres <[email protected]>

import numpy as np

from matplotlib import (
artist, cbook, lines as mlines, axis as maxis, patches as mpatches,
rcParams)
from . import art3d, proj3d

@cbook.deprecated("3.1")
def get_flip_min_max(coord, index, mins, maxs):
if coord[index] == mins[index]:
return maxs[index]
else:
return mins[index]

def move_from_center(coord, centers, deltas, axmask=(True, True, True)):
"""
For each coordinate where *axmask* is True, move *coord* away from
*centers* by *deltas*.
"""
coord = np.asarray(coord)
return coord + axmask * np.copysign(1, coord - centers) * deltas

def tick_update_position(tick, tickxs, tickys, labelpos):
'''Update tick line and label position and style.'''

tick.label1.set_position(labelpos)
tick.label2.set_position(labelpos)
tick.tick1line.set_visible(True)
tick.tick2line.set_visible(False)
tick.tick1line.set_linestyle('-')
tick.tick1line.set_marker('')
tick.tick1line.set_data(tickxs, tickys)
tick.gridline.set_data(0, 0)

[docs]class Axis(maxis.XAxis): """An Axis class for the 3D plots.""" # These points from the unit cube make up the x, y and z-planes _PLANES = ( (0, 3, 7, 4), (1, 2, 6, 5), # yz planes (0, 1, 5, 4), (3, 2, 6, 7), # xz planes (0, 1, 2, 3), (4, 5, 6, 7), # xy planes ) # Some properties for the axes _AXINFO = { 'x': {'i': 0, 'tickdir': 1, 'juggled': (1, 0, 2), 'color': (0.95, 0.95, 0.95, 0.5)}, 'y': {'i': 1, 'tickdir': 0, 'juggled': (0, 1, 2), 'color': (0.90, 0.90, 0.90, 0.5)}, 'z': {'i': 2, 'tickdir': 0, 'juggled': (0, 2, 1), 'color': (0.925, 0.925, 0.925, 0.5)}, } def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, rotate_label=None, **kwargs): # adir identifies which axes this is self.adir = adir # This is a temporary member variable. # Do not depend on this existing in future releases! self._axinfo = self._AXINFO[adir].copy() if rcParams['_internal.classic_mode']: self._axinfo.update( {'label': {'va': 'center', 'ha': 'center'}, 'tick': {'inward_factor': 0.2, 'outward_factor': 0.1, 'linewidth': rcParams['lines.linewidth']}, 'axisline': {'linewidth': 0.75, 'color': (0, 0, 0, 1)}, 'grid': {'color': (0.9, 0.9, 0.9, 1), 'linewidth': 1.0, 'linestyle': '-'}, }) else: self._axinfo.update( {'label': {'va': 'center', 'ha': 'center'}, 'tick': {'inward_factor': 0.2, 'outward_factor': 0.1, 'linewidth': rcParams.get( adir + 'tick.major.width', rcParams['xtick.major.width'])}, 'axisline': {'linewidth': rcParams['axes.linewidth'], 'color': rcParams['axes.edgecolor']}, 'grid': {'color': rcParams['grid.color'], 'linewidth': rcParams['grid.linewidth'], 'linestyle': rcParams['grid.linestyle']}, }) maxis.XAxis.__init__(self, axes, *args, **kwargs) # data and viewing intervals for this direction self.d_interval = d_intervalx self.v_interval = v_intervalx self.set_rotate_label(rotate_label)
[docs] def init3d(self): self.line = mlines.Line2D( xdata=(0, 0), ydata=(0, 0), linewidth=self._axinfo['axisline']['linewidth'], color=self._axinfo['axisline']['color'], antialiased=True) # Store dummy data in Polygon object self.pane = mpatches.Polygon( np.array([[0, 0], [0, 1], [1, 0], [0, 0]]), closed=False, alpha=0.8, facecolor='k', edgecolor='k') self.set_pane_color(self._axinfo['color']) self.axes._set_artist_props(self.line) self.axes._set_artist_props(self.pane) self.gridlines = art3d.Line3DCollection([]) self.axes._set_artist_props(self.gridlines) self.axes._set_artist_props(self.label) self.axes._set_artist_props(self.offsetText) # Need to be able to place the label at the correct location self.label._transform = self.axes.transData self.offsetText._transform = self.axes.transData
[docs] @cbook.deprecated("3.1") def get_tick_positions(self): majorLocs = self.major.locator() majorLabels = self.major.formatter.format_ticks(majorLocs) return majorLabels, majorLocs
[docs] def get_major_ticks(self, numticks=None): ticks = maxis.XAxis.get_major_ticks(self, numticks) for t in ticks: t.tick1line.set_transform(self.axes.transData) t.tick2line.set_transform(self.axes.transData) t.gridline.set_transform(self.axes.transData) t.label1.set_transform(self.axes.transData) t.label2.set_transform(self.axes.transData) return ticks
[docs] def set_pane_pos(self, xys): xys = np.asarray(xys) xys = xys[:, :2] self.pane.xy = xys self.stale = True
[docs] def set_pane_color(self, color): '''Set pane color to a RGBA tuple.''' self._axinfo['color'] = color self.pane.set_edgecolor(color) self.pane.set_facecolor(color) self.pane.set_alpha(color[-1]) self.stale = True
[docs] def set_rotate_label(self, val): ''' Whether to rotate the axis label: True, False or None. If set to None the label will be rotated if longer than 4 chars. ''' self._rotate_label = val self.stale = True
[docs] def get_rotate_label(self, text): if self._rotate_label is not None: return self._rotate_label else: return len(text) > 4
def _get_coord_info(self, renderer): mins, maxs = np.array([ self.axes.get_xbound(), self.axes.get_ybound(), self.axes.get_zbound(), ]).T centers = (maxs + mins) / 2. deltas = (maxs - mins) / 12. mins = mins - deltas / 4. maxs = maxs + deltas / 4. vals = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2] tc = self.axes.tunit_cube(vals, renderer.M) avgz = [tc[p1][2] + tc[p2][2] + tc[p3][2] + tc[p4][2] for p1, p2, p3, p4 in self._PLANES] highs = np.array([avgz[2*i] < avgz[2*i+1] for i in range(3)]) return mins, maxs, centers, deltas, tc, highs
[docs] def draw_pane(self, renderer): renderer.open_group('pane3d', gid=self.get_gid()) mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) info = self._axinfo index = info['i'] if not highs[index]: plane = self._PLANES[2 * index] else: plane = self._PLANES[2 * index + 1] xys = [tc[p] for p in plane] self.set_pane_pos(xys) self.pane.draw(renderer) renderer.close_group('pane3d')