aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/mpl_toolkits/axisartist
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:26:52 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:57:59 +0300
commitf895bba65827952ed934b2b46f9a45e30a191fd2 (patch)
tree03260c906d9ec41cdc03e2a496b15d407459cec0 /contrib/python/matplotlib/py2/mpl_toolkits/axisartist
parent5f7060466f7b9707818c2091e1a25c14f33c3474 (diff)
downloadydb-f895bba65827952ed934b2b46f9a45e30a191fd2.tar.gz
Remove deps on pandas
<https://github.com/ydb-platform/ydb/pull/14418> <https://github.com/ydb-platform/ydb/pull/14419> \-- аналогичные правки в gh Хочу залить в обход синка, чтобы посмотреть удалится ли pandas в нашей gh репе через piglet commit_hash:abca127aa37d4dbb94b07e1e18cdb8eb5b711860
Diffstat (limited to 'contrib/python/matplotlib/py2/mpl_toolkits/axisartist')
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py26
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py416
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py9
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py30
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py11
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py1527
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py168
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py828
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py135
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py544
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py340
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py475
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py18
13 files changed, 0 insertions, 4527 deletions
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py
deleted file mode 100644
index 8431c0cd3ee..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .axislines import (
- Axes, AxesZero, AxisArtistHelper, AxisArtistHelperRectlinear,
- GridHelperBase, GridHelperRectlinear, Subplot, SubplotZero)
-from .axis_artist import AxisArtist, GridlinesCollection
-
-from .grid_helper_curvelinear import GridHelperCurveLinear
-
-from .floating_axes import FloatingAxes, FloatingSubplot
-
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory,
- parasite_axes_auxtrans_class_factory, subplot_class_factory)
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-ParasiteAxesAuxTrans = \
- parasite_axes_auxtrans_class_factory(axes_class=ParasiteAxes)
-
-HostAxes = host_axes_class_factory(axes_class=Axes)
-
-SubplotHost = subplot_class_factory(HostAxes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py
deleted file mode 100644
index 15732a58ec0..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py
+++ /dev/null
@@ -1,416 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-import math
-
-from mpl_toolkits.axisartist.grid_finder import ExtremeFinderSimple
-
-def select_step_degree(dv):
-
- degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520]
- degree_steps_ = [ 1, 2, 5, 10, 15, 30, 45, 90, 180, 360]
- degree_factors = [1.] * len(degree_steps_)
-
- minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45]
- minsec_steps_ = [1, 2, 3, 5, 10, 15, 20, 30]
-
- minute_limits_ = np.array(minsec_limits_) / 60
- minute_factors = [60.] * len(minute_limits_)
-
- second_limits_ = np.array(minsec_limits_) / 3600
- second_factors = [3600.] * len(second_limits_)
-
- degree_limits = np.concatenate([second_limits_,
- minute_limits_,
- degree_limits_])
-
- degree_steps = np.concatenate([minsec_steps_,
- minsec_steps_,
- degree_steps_])
-
- degree_factors = np.concatenate([second_factors,
- minute_factors,
- degree_factors])
-
- n = degree_limits.searchsorted(dv)
- step = degree_steps[n]
- factor = degree_factors[n]
-
- return step, factor
-
-
-
-def select_step_hour(dv):
-
- hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36]
- hour_steps_ = [1, 2 , 3, 4, 6, 8, 12, 18, 24]
- hour_factors = [1.] * len(hour_steps_)
-
- minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45]
- minsec_steps_ = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]
-
- minute_limits_ = np.array(minsec_limits_) / 60
- minute_factors = [60.] * len(minute_limits_)
-
- second_limits_ = np.array(minsec_limits_) / 3600
- second_factors = [3600.] * len(second_limits_)
-
- hour_limits = np.concatenate([second_limits_,
- minute_limits_,
- hour_limits_])
-
- hour_steps = np.concatenate([minsec_steps_,
- minsec_steps_,
- hour_steps_])
-
- hour_factors = np.concatenate([second_factors,
- minute_factors,
- hour_factors])
-
- n = hour_limits.searchsorted(dv)
- step = hour_steps[n]
- factor = hour_factors[n]
-
- return step, factor
-
-
-def select_step_sub(dv):
-
- # subarcsec or degree
- tmp = 10.**(int(math.log10(dv))-1.)
-
- factor = 1./tmp
-
- if 1.5*tmp >= dv:
- step = 1
- elif 3.*tmp >= dv:
- step = 2
- elif 7.*tmp >= dv:
- step = 5
- else:
- step = 1
- factor = 0.1*factor
-
- return step, factor
-
-
-def select_step(v1, v2, nv, hour=False, include_last=True,
- threshold_factor=3600.):
-
- if v1 > v2:
- v1, v2 = v2, v1
-
- dv = (v2 - v1) / nv
-
- if hour:
- _select_step = select_step_hour
- cycle = 24.
- else:
- _select_step = select_step_degree
- cycle = 360.
-
- # for degree
- if dv > 1./threshold_factor:
- step, factor = _select_step(dv)
- else:
- step, factor = select_step_sub(dv*threshold_factor)
-
- factor = factor * threshold_factor
-
-
- f1, f2, fstep = v1*factor, v2*factor, step/factor
- levs = np.arange(np.floor(f1/step), np.ceil(f2/step)+0.5, dtype=int) * step
-
- # n : number of valid levels. If there is a cycle, e.g., [0, 90, 180,
- # 270, 360], the grid line needs to be extended from 0 to 360, so
- # we need to return the whole array. However, the last level (360)
- # needs to be ignored often. In this case, so we return n=4.
-
- n = len(levs)
-
-
- # we need to check the range of values
- # for example, -90 to 90, 0 to 360,
-
- if factor == 1. and (levs[-1] >= levs[0]+cycle): # check for cycle
- nv = int(cycle / step)
- if include_last:
- levs = levs[0] + np.arange(0, nv+1, 1) * step
- else:
- levs = levs[0] + np.arange(0, nv, 1) * step
-
- n = len(levs)
-
- return np.array(levs), n, factor
-
-
-def select_step24(v1, v2, nv, include_last=True, threshold_factor=3600):
- v1, v2 = v1/15., v2/15.
- levs, n, factor = select_step(v1, v2, nv, hour=True,
- include_last=include_last,
- threshold_factor=threshold_factor)
- return levs*15., n, factor
-
-def select_step360(v1, v2, nv, include_last=True, threshold_factor=3600):
- return select_step(v1, v2, nv, hour=False,
- include_last=include_last,
- threshold_factor=threshold_factor)
-
-
-class LocatorBase(object):
- def __init__(self, den, include_last=True):
- self.den = den
- self._include_last = include_last
-
- @property
- def nbins(self):
- return self.den
-
- @nbins.setter
- def nbins(self, v):
- self.den = v
-
- def set_params(self, nbins=None):
- if nbins is not None:
- self.den = int(nbins)
-
-
-class LocatorHMS(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.den, self._include_last)
-
-class LocatorHM(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.den, self._include_last,
- threshold_factor=60)
-
-class LocatorH(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.den, self._include_last,
- threshold_factor=1)
-
-
-class LocatorDMS(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.den, self._include_last)
-
-class LocatorDM(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.den, self._include_last,
- threshold_factor=60)
-
-class LocatorD(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.den, self._include_last,
- threshold_factor=1)
-
-
-class FormatterDMS(object):
- deg_mark = r"^{\circ}"
- min_mark = r"^{\prime}"
- sec_mark = r"^{\prime\prime}"
-
- fmt_d = "$%d" + deg_mark + "$"
- fmt_ds = r"$%d.%s" + deg_mark + "$"
-
- # %s for sign
- fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark + "$"
- fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark + "$"
-
- fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\,"
- fmt_s_partial = "%02d" + sec_mark + "$"
- fmt_ss_partial = "%02d.%s" + sec_mark + "$"
-
- def _get_number_fraction(self, factor):
- ## check for fractional numbers
- number_fraction = None
- # check for 60
-
- for threshold in [1, 60, 3600]:
- if factor <= threshold:
- break
-
- d = factor // threshold
- int_log_d = int(np.floor(np.log10(d)))
- if 10**int_log_d == d and d != 1:
- number_fraction = int_log_d
- factor = factor // 10**int_log_d
- return factor, number_fraction
-
- return factor, number_fraction
-
-
- def __call__(self, direction, factor, values):
- if len(values) == 0:
- return []
- #ss = [[-1, 1][v>0] for v in values] #not py24 compliant
- values = np.asarray(values)
- ss = np.where(values>0, 1, -1)
-
- sign_map = {(-1, True):"-"}
- signs = [sign_map.get((s, v!=0), "") for s, v in zip(ss, values)]
-
- factor, number_fraction = self._get_number_fraction(factor)
-
- values = np.abs(values)
-
- if number_fraction is not None:
- values, frac_part = divmod(values, 10**number_fraction)
- frac_fmt = "%%0%dd" % (number_fraction,)
- frac_str = [frac_fmt % (f1,) for f1 in frac_part]
-
- if factor == 1:
- if number_fraction is None:
- return [self.fmt_d % (s*int(v),) for (s, v) in zip(ss, values)]
- else:
- return [self.fmt_ds % (s*int(v), f1)
- for (s, v, f1) in zip(ss, values, frac_str)]
- elif factor == 60:
- deg_part, min_part = divmod(values, 60)
- if number_fraction is None:
- return [self.fmt_d_m % (s1, d1, m1)
- for s1, d1, m1 in zip(signs, deg_part, min_part)]
- else:
- return [self.fmt_d_ms % (s, d1, m1, f1)
- for s, d1, m1, f1 in zip(signs, deg_part, min_part, frac_str)]
-
- elif factor == 3600:
- if ss[-1] == -1:
- inverse_order = True
- values = values[::-1]
- signs = signs[::-1]
- else:
- inverse_order = False
-
- l_hm_old = ""
- r = []
-
- deg_part, min_part_ = divmod(values, 3600)
- min_part, sec_part = divmod(min_part_, 60)
-
- if number_fraction is None:
- sec_str = [self.fmt_s_partial % (s1,) for s1 in sec_part]
- else:
- sec_str = [self.fmt_ss_partial % (s1, f1) for s1, f1 in zip(sec_part, frac_str)]
-
- for s, d1, m1, s1 in zip(signs, deg_part, min_part, sec_str):
- l_hm = self.fmt_d_m_partial % (s, d1, m1)
- if l_hm != l_hm_old:
- l_hm_old = l_hm
- l = l_hm + s1 #l_s
- else:
- l = "$" + s + s1
- r.append(l)
-
- if inverse_order:
- return r[::-1]
- else:
- return r
-
- else: # factor > 3600.
- return [r"$%s^{\circ}$" % (str(v),) for v in ss*values]
-
-
-class FormatterHMS(FormatterDMS):
- deg_mark = r"^\mathrm{h}"
- min_mark = r"^\mathrm{m}"
- sec_mark = r"^\mathrm{s}"
-
- fmt_d = "$%d" + deg_mark + "$"
- fmt_ds = r"$%d.%s" + deg_mark + "$"
-
- # %s for sign
- fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark+"$"
- fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark+"$"
-
- fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\,"
- fmt_s_partial = "%02d" + sec_mark + "$"
- fmt_ss_partial = "%02d.%s" + sec_mark + "$"
-
- def __call__(self, direction, factor, values): # hour
- return FormatterDMS.__call__(self, direction, factor, np.asarray(values)/15.)
-
-
-
-
-
-class ExtremeFinderCycle(ExtremeFinderSimple):
- """
- When there is a cycle, e.g., longitude goes from 0-360.
- """
- def __init__(self,
- nx, ny,
- lon_cycle = 360.,
- lat_cycle = None,
- lon_minmax = None,
- lat_minmax = (-90, 90)
- ):
- #self.transfrom_xy = transform_xy
- #self.inv_transfrom_xy = inv_transform_xy
- self.nx, self.ny = nx, ny
- self.lon_cycle, self.lat_cycle = lon_cycle, lat_cycle
- self.lon_minmax = lon_minmax
- self.lat_minmax = lat_minmax
-
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- get extreme values.
-
- x1, y1, x2, y2 in image coordinates (0-based)
- nx, ny : number of divisions in each axis
- """
- x_, y_ = np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)
- x, y = np.meshgrid(x_, y_)
- lon, lat = transform_xy(np.ravel(x), np.ravel(y))
-
- # iron out jumps, but algorithm should be improved.
- # This is just naive way of doing and my fail for some cases.
- # Consider replacing this with numpy.unwrap
- # We are ignoring invalid warnings. They are triggered when
- # comparing arrays with NaNs using > We are already handling
- # that correctly using np.nanmin and np.nanmax
- with np.errstate(invalid='ignore'):
- if self.lon_cycle is not None:
- lon0 = np.nanmin(lon)
- lon -= 360. * ((lon - lon0) > 180.)
- if self.lat_cycle is not None:
- lat0 = np.nanmin(lat)
- lat -= 360. * ((lat - lat0) > 180.)
-
- lon_min, lon_max = np.nanmin(lon), np.nanmax(lon)
- lat_min, lat_max = np.nanmin(lat), np.nanmax(lat)
-
- lon_min, lon_max, lat_min, lat_max = \
- self._adjust_extremes(lon_min, lon_max, lat_min, lat_max)
-
- return lon_min, lon_max, lat_min, lat_max
-
-
- def _adjust_extremes(self, lon_min, lon_max, lat_min, lat_max):
-
- lon_min, lon_max, lat_min, lat_max = \
- self._add_pad(lon_min, lon_max, lat_min, lat_max)
-
- # check cycle
- if self.lon_cycle:
- lon_max = min(lon_max, lon_min + self.lon_cycle)
- if self.lat_cycle:
- lat_max = min(lat_max, lat_min + self.lat_cycle)
-
- if self.lon_minmax is not None:
- min0 = self.lon_minmax[0]
- lon_min = max(min0, lon_min)
- max0 = self.lon_minmax[1]
- lon_max = min(max0, lon_max)
-
- if self.lat_minmax is not None:
- min0 = self.lat_minmax[0]
- lat_min = max(min0, lat_min)
- max0 = self.lat_minmax[1]
- lat_max = min(max0, lat_max)
-
- return lon_min, lon_max, lat_min, lat_max
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py
deleted file mode 100644
index 52949405302..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.axes_divider import (
- Divider, AxesLocator, SubplotDivider, AxesDivider, locatable_axes_factory,
- make_axes_locatable)
-
-from mpl_toolkits.axes_grid.axislines import Axes
-LocatableAxes = locatable_axes_factory(Axes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py
deleted file mode 100644
index 58212ac89c4..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig
-from .axes_divider import LocatableAxes
-
-class CbarAxes(axes_grid_orig.CbarAxesBase, LocatableAxes):
- def __init__(self, *kl, **kwargs):
- orientation=kwargs.pop("orientation", None)
- if orientation is None:
- raise ValueError("orientation must be specified")
- self.orientation = orientation
- self._default_label_on = False
- self.locator = None
-
- super(LocatableAxes, self).__init__(*kl, **kwargs)
-
- def cla(self):
- super(LocatableAxes, self).cla()
- self._config_axes()
-
-
-class Grid(axes_grid_orig.Grid):
- _defaultLocatableAxesClass = LocatableAxes
-
-class ImageGrid(axes_grid_orig.ImageGrid):
- _defaultLocatableAxesClass = LocatableAxes
- _defaultCbarAxesClass = CbarAxes
-
-AxesGrid = ImageGrid
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py
deleted file mode 100644
index 695a362b57d..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.axes_rgb import (
- make_rgb_axes, imshow_rgb, RGBAxesBase)
-
-from .axislines import Axes
-
-
-class RGBAxes(RGBAxesBase):
- _defaultAxesClass = Axes
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py
deleted file mode 100644
index 620232112cf..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py
+++ /dev/null
@@ -1,1527 +0,0 @@
-"""
-axis_artist.py module provides axis-related artists. They are
-
- * axis line
- * tick lines
- * tick labels
- * axis label
- * grid lines
-
-The main artist class is a AxisArtist and a GridlinesCollection. The
-GridlinesCollection is responsible for drawing grid lines and the
-AxisArtist is responsible for all other artists. The AxisArtist class
-has attributes that are associated with each type of artists.
-
- * line : axis line
- * major_ticks : major tick lines
- * major_ticklabels : major tick labels
- * minor_ticks : minor tick lines
- * minor_ticklabels : minor tick labels
- * label : axis label
-
-Typically, the AxisArtist associated with a axes will be accessed with
-the *axis* dictionary of the axes, i.e., the AxisArtist for the bottom
-axis is
-
- ax.axis["bottom"]
-
-where *ax* is an instance of axes (mpl_toolkits.axislines.Axes). Thus,
-ax.axis["bottom"].line is an artist associated with the axis line, and
-ax.axis["bottom"].major_ticks is an artist associated with the major tick
-lines.
-
-You can change the colors, fonts, line widths, etc. of these artists
-by calling suitable set method. For example, to change the color of the major
-ticks of the bottom axis to red,
-
- ax.axis["bottom"].major_ticks.set_color("r")
-
-However, things like the locations of ticks, and their ticklabels need
-to be changed from the side of the grid_helper.
-
-axis_direction
---------------
-
-AxisArtist, AxisLabel, TickLabels have *axis_direction* attribute,
-which adjusts the location, angle, etc.,. The *axis_direction* must be
-one of [left, right, bottom, top] and they follow the matplotlib
-convention for the rectangle axis.
-
-For example, for the *bottom* axis (the left and right is relative to
-the direction of the increasing coordinate),
-
- * ticklabels and axislabel are on the right
- * ticklabels and axislabel have text angle of 0
- * ticklabels are baseline, center-aligned
- * axislabel is top, center-aligned
-
-
-The text angles are actually relative to (90 + angle of the direction
-to the ticklabel), which gives 0 for bottom axis.
-
- Parameter left bottom right top
- ticklabels location left right right left
- axislabel location left right right left
- ticklabels angle 90 0 -90 180
- axislabel angle 180 0 0 180
- ticklabel va center baseline center baseline
- axislabel va center top center bottom
- ticklabel ha right center right center
- axislabel ha right center right center
-
-
-Ticks are by default direct opposite side of the ticklabels. To make
-ticks to the same side of the ticklabels,
-
- ax.axis["bottom"].major_ticks.set_ticks_out(True)
-
-
-Following attributes can be customized (use set_xxx method)
-
- * Ticks : ticksize, tick_out
- * TickLabels : pad
- * AxisLabel : pad
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-# FIXME :
-# angles are given in data coordinate - need to convert it to canvas coordinate
-
-
-import matplotlib.artist as martist
-import matplotlib.text as mtext
-import matplotlib.font_manager as font_manager
-
-from matplotlib.path import Path
-from matplotlib.transforms import (
- Affine2D, Bbox, IdentityTransform, ScaledTranslation, TransformedPath)
-from matplotlib.collections import LineCollection
-
-from matplotlib import rcParams
-
-from matplotlib.artist import allow_rasterization
-
-import warnings
-
-import numpy as np
-
-
-import matplotlib.lines as mlines
-from .axisline_style import AxislineStyle
-
-
-class BezierPath(mlines.Line2D):
-
- def __init__(self, path, *kl, **kw):
- mlines.Line2D.__init__(self, [], [], *kl, **kw)
- self._path = path
- self._invalid = False
-
- def recache(self):
-
- self._transformed_path = TransformedPath(self._path, self.get_transform())
-
- self._invalid = False
-
- def set_path(self, path):
- self._path = path
- self._invalid = True
-
-
- def draw(self, renderer):
- if self._invalid:
- self.recache()
-
- if not self._visible: return
- renderer.open_group('line2d')
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
-
- gc.set_foreground(self._color)
- gc.set_antialiased(self._antialiased)
- gc.set_linewidth(self._linewidth)
- gc.set_alpha(self._alpha)
- if self.is_dashed():
- cap = self._dashcapstyle
- join = self._dashjoinstyle
- else:
- cap = self._solidcapstyle
- join = self._solidjoinstyle
- gc.set_joinstyle(join)
- gc.set_capstyle(cap)
- gc.set_dashes(self._dashOffset, self._dashSeq)
-
- if self._lineStyles[self._linestyle] != '_draw_nothing':
- tpath, affine = (
- self._transformed_path.get_transformed_path_and_affine())
- renderer.draw_path(gc, tpath, affine.frozen())
-
- gc.restore()
- renderer.close_group('line2d')
-
-
-
-class UnimplementedException(Exception):
- pass
-
-from matplotlib.artist import Artist
-
-class AttributeCopier(object):
- def __init__(self, ref_artist, klass=Artist):
- self._klass = klass
- self._ref_artist = ref_artist
- super(AttributeCopier, self).__init__()
-
- def set_ref_artist(self, artist):
- self._ref_artist = artist
-
- def get_ref_artist(self):
- raise RuntimeError("get_ref_artist must overridden")
- #return self._ref_artist
-
- def get_attribute_from_ref_artist(self, attr_name, default_value):
- get_attr_method_name = "get_"+attr_name
- c = getattr(self._klass, get_attr_method_name)(self)
- if c == 'auto':
- ref_artist = self.get_ref_artist()
- if ref_artist:
- attr = getattr(ref_artist,
- get_attr_method_name)()
- return attr
- else:
- return default_value
-
- return c
-
-
-from matplotlib.lines import Line2D
-
-class Ticks(Line2D, AttributeCopier):
- """
- Ticks are derived from Line2D, and note that ticks themselves
- are markers. Thus, you should use set_mec, set_mew, etc.
-
- To change the tick size (length), you need to use
- set_ticksize. To change the direction of the ticks (ticks are
- in opposite direction of ticklabels by default), use
- set_tick_out(False).
- """
-
- def __init__(self, ticksize, tick_out=False, **kwargs):
- self._ticksize = ticksize
- self.locs_angles_labels = []
-
- self.set_tick_out(tick_out)
-
- self._axis = kwargs.pop("axis", None)
- if self._axis is not None:
- if "color" not in kwargs:
- kwargs["color"] = "auto"
- if ("mew" not in kwargs) and ("markeredgewidth" not in kwargs):
- kwargs["markeredgewidth"] = "auto"
-
- Line2D.__init__(self, [0.], [0.], **kwargs)
- AttributeCopier.__init__(self, self._axis, klass=Line2D)
- self.set_snap(True)
-
- def get_ref_artist(self):
- #return self._ref_artist.get_ticklines()[0]
- return self._ref_artist.majorTicks[0].tick1line
-
- def get_color(self):
- return self.get_attribute_from_ref_artist("color", "k")
-
- def get_markeredgecolor(self):
- if self._markeredgecolor == 'auto':
- return self.get_color()
- else:
- return self._markeredgecolor
-
- def get_markeredgewidth(self):
- return self.get_attribute_from_ref_artist("markeredgewidth", .5)
-
-
- def set_tick_out(self, b):
- """
- set True if tick need to be rotated by 180 degree.
- """
- self._tick_out = b
-
- def get_tick_out(self):
- """
- Return True if the tick will be rotated by 180 degree.
- """
- return self._tick_out
-
-
- def set_ticksize(self, ticksize):
- """
- set length of the ticks in points.
- """
- self._ticksize = ticksize
-
-
- def get_ticksize(self):
- """
- Return length of the ticks in points.
- """
- return self._ticksize
-
- def set_locs_angles(self, locs_angles):
- self.locs_angles = locs_angles
-
-
- def _update(self, renderer):
- pass
-
- _tickvert_path = Path([[0., 0.], [1., 0.]])
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- self._update(renderer) # update the tick
-
- size = self._ticksize
- path_trans = self.get_transform()
-
- # set gc : copied from lines.py
-# gc = renderer.new_gc()
-# self._set_gc_clip(gc)
-
-# gc.set_foreground(self.get_color())
-# gc.set_antialiased(self._antialiased)
-# gc.set_linewidth(self._linewidth)
-# gc.set_alpha(self._alpha)
-# if self.is_dashed():
-# cap = self._dashcapstyle
-# join = self._dashjoinstyle
-# else:
-# cap = self._solidcapstyle
-# join = self._solidjoinstyle
-# gc.set_joinstyle(join)
-# gc.set_capstyle(cap)
-# gc.set_snap(self.get_snap())
-
-
- gc = renderer.new_gc()
- gc.set_foreground(self.get_markeredgecolor())
- gc.set_linewidth(self.get_markeredgewidth())
- gc.set_alpha(self._alpha)
-
- offset = renderer.points_to_pixels(size)
- marker_scale = Affine2D().scale(offset, offset)
-
- if self.get_tick_out():
- add_angle = 180
- else:
- add_angle = 0
-
- marker_rotation = Affine2D()
- marker_transform = marker_scale + marker_rotation
-
- for loc, angle in self.locs_angles:
- marker_rotation.clear().rotate_deg(angle+add_angle)
- locs = path_trans.transform_non_affine(np.array([loc]))
- if self.axes and not self.axes.viewLim.contains(*locs[0]):
- continue
- renderer.draw_markers(gc, self._tickvert_path, marker_transform,
- Path(locs), path_trans.get_affine())
-
- gc.restore()
-
-
-class LabelBase(mtext.Text):
- """
- A base class for AxisLabel and TickLabels. The position and angle
- of the text are calculated by to offset_ref_angle,
- text_ref_angle, and offset_radius attributes.
- """
-
- def __init__(self, *kl, **kwargs):
- self.locs_angles_labels = []
- self._ref_angle = 0
- self._offset_radius = 0.
-
- super(LabelBase, self).__init__(*kl,
- **kwargs)
-
- self.set_rotation_mode("anchor")
- self._text_follow_ref_angle = True
- #self._offset_ref_angle = 0
-
- def _set_ref_angle(self, a):
- self._ref_angle = a
-
- def _get_ref_angle(self):
- return self._ref_angle
-
- def _get_text_ref_angle(self):
- if self._text_follow_ref_angle:
- return self._get_ref_angle()+90
- else:
- return 0 #self.get_ref_angle()
-
- def _get_offset_ref_angle(self):
- return self._get_ref_angle()
-
- def _set_offset_radius(self, offset_radius):
- self._offset_radius = offset_radius
-
- def _get_offset_radius(self):
- return self._offset_radius
-
-
- _get_opposite_direction = {"left":"right",
- "right":"left",
- "top":"bottom",
- "bottom":"top"}.__getitem__
-
-
- def _update(self, renderer):
- pass
-
- def draw(self, renderer):
- if not self.get_visible(): return
-
- self._update(renderer)
-
- # save original and adjust some properties
- tr = self.get_transform()
- angle_orig = self.get_rotation()
-
- offset_tr = Affine2D()
- self.set_transform(tr+offset_tr)
-
- text_ref_angle = self._get_text_ref_angle()
- offset_ref_angle = self._get_offset_ref_angle()
-
- theta = (offset_ref_angle)/180.*np.pi
- dd = self._get_offset_radius()
- dx, dy = dd * np.cos(theta), dd * np.sin(theta)
- offset_tr.translate(dx, dy)
- self.set_rotation(text_ref_angle+angle_orig)
- super(LabelBase, self).draw(renderer)
- offset_tr.clear()
-
-
- # restore original properties
- self.set_transform(tr)
- self.set_rotation(angle_orig)
-
-
- def get_window_extent(self, renderer):
-
- self._update(renderer)
-
- # save original and adjust some properties
- tr = self.get_transform()
- angle_orig = self.get_rotation()
-
- offset_tr = Affine2D()
- self.set_transform(tr+offset_tr)
-
- text_ref_angle = self._get_text_ref_angle()
- offset_ref_angle = self._get_offset_ref_angle()
-
- theta = (offset_ref_angle)/180.*np.pi
- dd = self._get_offset_radius()
- dx, dy = dd * np.cos(theta), dd * np.sin(theta)
- offset_tr.translate(dx, dy)
- self.set_rotation(text_ref_angle+angle_orig)
-
- bbox = super(LabelBase, self).get_window_extent(renderer).frozen()
-
- offset_tr.clear()
-
-
- # restore original properties
- self.set_transform(tr)
- self.set_rotation(angle_orig)
-
- return bbox
-
-
-class AxisLabel(LabelBase, AttributeCopier):
- """
- Axis Label. Derived from Text. The position of the text is updated
- in the fly, so changing text position has no effect. Otherwise, the
- properties can be changed as a normal Text.
-
- To change the pad between ticklabels and axis label, use set_pad.
- """
-
- def __init__(self, *kl, **kwargs):
-
- axis_direction = kwargs.pop("axis_direction", "bottom")
- self._axis = kwargs.pop("axis", None)
- #super(AxisLabel, self).__init__(*kl, **kwargs)
- LabelBase.__init__(self, *kl, **kwargs)
- AttributeCopier.__init__(self, self._axis, klass=LabelBase)
-
- self.set_axis_direction(axis_direction)
- self._pad = 5
- self._extra_pad = 0
-
- def set_pad(self, pad):
- """
- Set the pad in points. Note that the actual pad will be the
- sum of the internal pad and the external pad (that are set
- automatically by the AxisArtist), and it only set the internal
- pad
- """
- self._pad = pad
-
- def get_pad(self):
- """
- return pad in points. See set_pad for more details.
- """
- return self._pad
-
-
- def _set_external_pad(self, p):
- """
- Set external pad IN PIXELS. This is intended to be set by the
- AxisArtist, bot by user..
- """
- self._extra_pad = p
-
- def _get_external_pad(self):
- """
- Get external pad.
- """
- return self._extra_pad
-
-
- def get_ref_artist(self):
- return self._axis.get_label()
-
-
- def get_text(self):
- t = super(AxisLabel, self).get_text()
- if t == "__from_axes__":
- return self._axis.get_label().get_text()
- return self._text
-
- _default_alignments = dict(left=("bottom", "center"),
- right=("top", "center"),
- bottom=("top", "center"),
- top=("bottom", "center"))
-
-
-
- def set_default_alignment(self, d):
- if d not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
-
- va, ha = self._default_alignments[d]
- self.set_va(va)
- self.set_ha(ha)
-
-
- _default_angles = dict(left=180,
- right=0,
- bottom=0,
- top=180)
-
-
- def set_default_angle(self, d):
- if d not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
-
- self.set_rotation(self._default_angles[d])
-
-
- def set_axis_direction(self, d):
- """
- Adjust the text angle and text alignment of axis label
- according to the matplotlib convention.
-
-
- ===================== ========== ========= ========== ==========
- property left bottom right top
- ===================== ========== ========= ========== ==========
- axislabel angle 180 0 0 180
- axislabel va center top center bottom
- axislabel ha right center right center
- ===================== ========== ========= ========== ==========
-
- Note that the text angles are actually relative to (90 + angle
- of the direction to the ticklabel), which gives 0 for bottom
- axis.
-
- """
- if d not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
-
- self.set_default_alignment(d)
- self.set_default_angle(d)
-
- def get_color(self):
- return self.get_attribute_from_ref_artist("color", "k")
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- pad = renderer.points_to_pixels(self.get_pad())
- r = self._get_external_pad() + pad
- self._set_offset_radius(r)
-
- super(AxisLabel, self).draw(renderer)
-
-
- def get_window_extent(self, renderer):
-
- if not self.get_visible():
- return
-
- pad = renderer.points_to_pixels(self.get_pad())
- r = self._get_external_pad() + pad
- self._set_offset_radius(r)
-
- bb = super(AxisLabel, self).get_window_extent(renderer)
-
- return bb
-
-
-class TickLabels(AxisLabel, AttributeCopier): # mtext.Text
- """
- Tick Labels. While derived from Text, this single artist draws all
- ticklabels. As in AxisLabel, the position of the text is updated
- in the fly, so changing text position has no effect. Otherwise,
- the properties can be changed as a normal Text. Unlike the
- ticklabels of the mainline matplotlib, properties of single
- ticklabel alone cannot modified.
-
- To change the pad between ticks and ticklabels, use set_pad.
- """
-
- def __init__(self, **kwargs):
-
- axis_direction = kwargs.pop("axis_direction", "bottom")
- AxisLabel.__init__(self, **kwargs)
- self.set_axis_direction(axis_direction)
- #self._axis_direction = axis_direction
- self._axislabel_pad = 0
- #self._extra_pad = 0
-
-
- # attribute copier
- def get_ref_artist(self):
- return self._axis.get_ticklabels()[0]
-
- def set_axis_direction(self, label_direction):
- """
- Adjust the text angle and text alignment of ticklabels
- according to the matplotlib convention.
-
- The *label_direction* must be one of [left, right, bottom,
- top].
-
- ===================== ========== ========= ========== ==========
- property left bottom right top
- ===================== ========== ========= ========== ==========
- ticklabels angle 90 0 -90 180
- ticklabel va center baseline center baseline
- ticklabel ha right center right center
- ===================== ========== ========= ========== ==========
-
-
- Note that the text angles are actually relative to (90 + angle
- of the direction to the ticklabel), which gives 0 for bottom
- axis.
-
- """
-
- if label_direction not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be one of "left", "right", "top", "bottom"')
-
- self._axis_direction = label_direction
- self.set_default_alignment(label_direction)
- self.set_default_angle(label_direction)
-
-
- def invert_axis_direction(self):
- label_direction = self._get_opposite_direction(self._axis_direction)
- self.set_axis_direction(label_direction)
-
- def _get_ticklabels_offsets(self, renderer, label_direction):
- """
- Calculates the offsets of the ticklabels from the tick and
- their total heights. The offset only takes account the offset
- due to the vertical alignment of the ticklabels, i.e.,if axis
- direction is bottom and va is ;top', it will return 0. if va
- is 'baseline', it will return (height-descent).
- """
- whd_list = self.get_texts_widths_heights_descents(renderer)
-
- if not whd_list:
- return 0, 0
-
- r = 0
- va, ha = self.get_va(), self.get_ha()
-
- if label_direction == "left":
- pad = max(w for w, h, d in whd_list)
- if ha == "left":
- r = pad
- elif ha == "center":
- r = .5 * pad
- elif label_direction == "right":
- pad = max(w for w, h, d in whd_list)
- if ha == "right":
- r = pad
- elif ha == "center":
- r = .5 * pad
- elif label_direction == "bottom":
- pad = max(h for w, h, d in whd_list)
- if va == "bottom":
- r = pad
- elif va == "center":
- r =.5 * pad
- elif va == "baseline":
- max_ascent = max(h - d for w, h, d in whd_list)
- max_descent = max(d for w, h, d in whd_list)
- r = max_ascent
- pad = max_ascent + max_descent
- elif label_direction == "top":
- pad = max(h for w, h, d in whd_list)
- if va == "top":
- r = pad
- elif va == "center":
- r =.5 * pad
- elif va == "baseline":
- max_ascent = max(h - d for w, h, d in whd_list)
- max_descent = max(d for w, h, d in whd_list)
- r = max_descent
- pad = max_ascent + max_descent
-
- #tick_pad = renderer.points_to_pixels(self.get_pad())
-
- # r : offset
-
- # pad : total height of the ticklabels. This will be used to
- # calculate the pad for the axislabel.
- return r, pad
-
-
-
- _default_alignments = dict(left=("center", "right"),
- right=("center", "left"),
- bottom=("baseline", "center"),
- top=("baseline", "center"))
-
-
-
- # set_default_alignments(self, d)
-
- _default_angles = dict(left=90,
- right=-90,
- bottom=0,
- top=180)
-
-
- def draw(self, renderer):
- if not self.get_visible():
- self._axislabel_pad = self._get_external_pad()
- return
-
- r, total_width = self._get_ticklabels_offsets(renderer,
- self._axis_direction)
-
- #self._set_external_pad(r+self._get_external_pad())
- pad = self._get_external_pad() + \
- renderer.points_to_pixels(self.get_pad())
- self._set_offset_radius(r+pad)
-
- #self._set_offset_radius(r)
-
- for (x, y), a, l in self._locs_angles_labels:
- if not l.strip(): continue
- self._set_ref_angle(a) #+ add_angle
- self.set_x(x)
- self.set_y(y)
- self.set_text(l)
- LabelBase.draw(self, renderer)
-
- self._axislabel_pad = total_width \
- + pad # the value saved will be used to draw axislabel.
-
-
- def set_locs_angles_labels(self, locs_angles_labels):
- self._locs_angles_labels = locs_angles_labels
-
- def get_window_extents(self, renderer):
-
- if not self.get_visible():
- self._axislabel_pad = self._get_external_pad()
- return []
-
- bboxes = []
-
- r, total_width = self._get_ticklabels_offsets(renderer,
- self._axis_direction)
-
- pad = self._get_external_pad() + \
- renderer.points_to_pixels(self.get_pad())
- self._set_offset_radius(r+pad)
-
-
- for (x, y), a, l in self._locs_angles_labels:
- self._set_ref_angle(a) #+ add_angle
- self.set_x(x)
- self.set_y(y)
- self.set_text(l)
- bb = LabelBase.get_window_extent(self, renderer)
- bboxes.append(bb)
-
- self._axislabel_pad = total_width \
- + pad # the value saved will be used to draw axislabel.
-
- return bboxes
-
-
- def get_texts_widths_heights_descents(self, renderer):
- """
- return a list of width, height, descent for ticklabels.
- """
- whd_list = []
- for (x, y), a, l in self._locs_angles_labels:
- if not l.strip(): continue
- clean_line, ismath = self.is_math_text(l)
- whd = renderer.get_text_width_height_descent(
- clean_line, self._fontproperties, ismath=ismath)
- whd_list.append(whd)
-
- return whd_list
-
-
-class GridlinesCollection(LineCollection):
- def __init__(self, *kl, **kwargs):
- """
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
- """
- self._which = kwargs.pop("which", "major")
- self._axis = kwargs.pop("axis", "both")
- super(GridlinesCollection, self).__init__(*kl, **kwargs)
- self.set_grid_helper(None)
-
- def set_which(self, which):
- self._which = which
-
- def set_axis(self, axis):
- self._axis = axis
-
- def set_grid_helper(self, grid_helper):
- self._grid_helper = grid_helper
-
- def draw(self, renderer):
- if self._grid_helper is not None:
- self._grid_helper.update_lim(self.axes)
- gl = self._grid_helper.get_gridlines(self._which, self._axis)
- if gl:
- self.set_segments([np.transpose(l) for l in gl])
- else:
- self.set_segments([])
- super(GridlinesCollection, self).draw(renderer)
-
-
-
-
-class AxisArtist(martist.Artist):
- """
- An artist which draws axis (a line along which the n-th axes coord
- is constant) line, ticks, ticklabels, and axis label.
- """
-
- ZORDER=2.5
-
- @property
- def LABELPAD(self):
- return self.label.get_pad()
-
- @LABELPAD.setter
- def LABELPAD(self, v):
- return self.label.set_pad(v)
-
- def __init__(self, axes,
- helper,
- offset=None,
- axis_direction="bottom",
- **kw):
- """
- *axes* : axes
- *helper* : an AxisArtistHelper instance.
- """
- #axes is also used to follow the axis attribute (tick color, etc).
-
- super(AxisArtist, self).__init__(**kw)
-
- self.axes = axes
-
- self._axis_artist_helper = helper
-
- if offset is None:
- offset = (0, 0)
- self.dpi_transform = Affine2D()
- self.offset_transform = ScaledTranslation(offset[0], offset[1],
- self.dpi_transform)
-
- self._label_visible = True
- self._majortick_visible = True
- self._majorticklabel_visible = True
- self._minortick_visible = True
- self._minorticklabel_visible = True
-
-
- #if self._axis_artist_helper._loc in ["left", "right"]:
- if axis_direction in ["left", "right"]:
- axis_name = "ytick"
- self.axis = axes.yaxis
- else:
- axis_name = "xtick"
- self.axis = axes.xaxis
-
-
- self._axisline_style = None
-
-
- self._axis_direction = axis_direction
-
-
- self._init_line()
- self._init_ticks(axis_name, **kw)
- self._init_offsetText(axis_direction)
- self._init_label()
-
- self.set_zorder(self.ZORDER)
-
- self._rotate_label_along_line = False
-
- # axis direction
- self._tick_add_angle = 180.
- self._ticklabel_add_angle = 0.
- self._axislabel_add_angle = 0.
- self.set_axis_direction(axis_direction)
-
-
- # axis direction
-
- def set_axis_direction(self, axis_direction):
- """
- Adjust the direction, text angle, text alignment of
- ticklabels, labels following the matplotlib convention for
- the rectangle axes.
-
- The *axis_direction* must be one of [left, right, bottom,
- top].
-
- ===================== ========== ========= ========== ==========
- property left bottom right top
- ===================== ========== ========= ========== ==========
- ticklabels location "-" "+" "+" "-"
- axislabel location "-" "+" "+" "-"
- ticklabels angle 90 0 -90 180
- ticklabel va center baseline center baseline
- ticklabel ha right center right center
- axislabel angle 180 0 0 180
- axislabel va center top center bottom
- axislabel ha right center right center
- ===================== ========== ========= ========== ==========
-
-
- Note that the direction "+" and "-" are relative to the direction of
- the increasing coordinate. Also, the text angles are actually
- relative to (90 + angle of the direction to the ticklabel),
- which gives 0 for bottom axis.
-
- """
-
- if axis_direction not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
- self._axis_direction = axis_direction
- if axis_direction in ["left", "top"]:
- #self._set_tick_direction("+")
- self.set_ticklabel_direction("-")
- self.set_axislabel_direction("-")
- else:
- #self._set_tick_direction("-")
- self.set_ticklabel_direction("+")
- self.set_axislabel_direction("+")
-
- self.major_ticklabels.set_axis_direction(axis_direction)
- self.label.set_axis_direction(axis_direction)
-
- # def _set_tick_direction(self, d):
- # if d not in ["+", "-"]:
- # raise ValueError('direction must be on of "in", "out"')
-
- # if d == "+":
- # self._tick_add_angle = 0 #get_helper()._extremes=0, 10
- # else:
- # self._tick_add_angle = 180 #get_helper()._extremes=0, 10
-
- def set_ticklabel_direction(self, tick_direction):
- """
- Adjust the direction of the ticklabel.
-
- ACCEPTS: [ "+" | "-" ]
-
- Note that the label_direction '+' and '-' are relative to the
- direction of the increasing coordinate.
- """
-
- if tick_direction not in ["+", "-"]:
- raise ValueError('direction must be one of "+", "-"')
-
- if tick_direction == "-":
- self._ticklabel_add_angle = 180
- else:
- self._ticklabel_add_angle = 0
-
- def invert_ticklabel_direction(self):
- self._ticklabel_add_angle = (self._ticklabel_add_angle + 180) % 360
- self.major_ticklabels.invert_axis_direction()
- self.minor_ticklabels.invert_axis_direction()
-
- # def invert_ticks_direction(self):
- # self.major_ticks.set_tick_out(not self.major_ticks.get_tick_out())
- # self.minor_ticks.set_tick_out(not self.minor_ticks.get_tick_out())
-
- def set_axislabel_direction(self, label_direction):
- """
- Adjust the direction of the axislabel.
-
- ACCEPTS: [ "+" | "-" ]
-
- Note that the label_direction '+' and '-' are relative to the
- direction of the increasing coordinate.
- """
- if label_direction not in ["+", "-"]:
- raise ValueError('direction must be one of "+", "-"')
-
- if label_direction == "-":
- self._axislabel_add_angle = 180
- else:
- self._axislabel_add_angle = 0
-
-
-
- def get_transform(self):
- return self.axes.transAxes + self.offset_transform
-
- def get_helper(self):
- """
- Return axis artist helper instance.
- """
- return self._axis_artist_helper
-
-
- def set_axisline_style(self, axisline_style=None, **kw):
- """
- Set the axisline style.
-
- *axisline_style* can be a string with axisline style name with optional
- comma-separated attributes. Alternatively, the attrs can
- be provided as keywords.
-
- set_arrowstyle("->,size=1.5")
- set_arrowstyle("->", size=1.5)
-
- Old attrs simply are forgotten.
-
- Without argument (or with arrowstyle=None), return
- available styles as a list of strings.
- """
-
- if axisline_style==None:
- return AxislineStyle.pprint_styles()
-
- if isinstance(axisline_style, AxislineStyle._Base):
- self._axisline_style = axisline_style
- else:
- self._axisline_style = AxislineStyle(axisline_style, **kw)
-
-
- self._init_line()
-
-
- def get_axisline_style(self):
- """
- return the current axisline style.
- """
- return self._axisline_style
-
- def _init_line(self):
- """
- Initialize the *line* artist that is responsible to draw the axis line.
- """
- tran = self._axis_artist_helper.get_line_transform(self.axes) \
- + self.offset_transform
-
- axisline_style = self.get_axisline_style()
- if axisline_style is None:
- self.line = BezierPath(self._axis_artist_helper.get_line(self.axes),
- color=rcParams['axes.edgecolor'],
- linewidth=rcParams['axes.linewidth'],
- transform=tran)
- else:
- self.line = axisline_style(self, transform=tran)
-
- def _draw_line(self, renderer):
- self.line.set_path(self._axis_artist_helper.get_line(self.axes))
- if self.get_axisline_style() is not None:
- self.line.set_line_mutation_scale(self.major_ticklabels.get_size())
- self.line.draw(renderer)
-
-
- def _init_ticks(self, axis_name, **kw):
-
- trans=self._axis_artist_helper.get_tick_transform(self.axes) \
- + self.offset_transform
-
-
- major_tick_size = kw.get("major_tick_size",
- rcParams['%s.major.size'%axis_name])
- major_tick_pad = kw.get("major_tick_pad",
- rcParams['%s.major.pad'%axis_name])
- minor_tick_size = kw.get("minor_tick_size",
- rcParams['%s.minor.size'%axis_name])
- minor_tick_pad = kw.get("minor_tick_pad",
- rcParams['%s.minor.pad'%axis_name])
-
- self.major_ticks = Ticks(major_tick_size,
- axis=self.axis,
- transform=trans)
- self.minor_ticks = Ticks(minor_tick_size,
- axis=self.axis,
- transform=trans)
-
- if axis_name == "xaxis":
- size = rcParams['xtick.labelsize']
- else:
- size = rcParams['ytick.labelsize']
-
-
- fontprops = font_manager.FontProperties(size=size)
-
- self.major_ticklabels = TickLabels(size=size, axis=self.axis,
- axis_direction=self._axis_direction)
- self.minor_ticklabels = TickLabels(size=size, axis=self.axis,
- axis_direction=self._axis_direction)
-
-
- self.major_ticklabels.set(figure = self.axes.figure,
- transform=trans,
- fontproperties=fontprops)
- self.major_ticklabels.set_pad(major_tick_pad)
-
- self.minor_ticklabels.set(figure = self.axes.figure,
- transform=trans,
- fontproperties=fontprops)
- self.minor_ticklabels.set_pad(minor_tick_pad)
-
-
-
- def _get_tick_info(self, tick_iter):
- """
- return ticks_loc_angle, ticklabels_loc_angle_label
-
- ticks_loc_angle : list of locs and angles for ticks
- ticklabels_loc_angle_label : list of locs, angles and labels for tickslabels
- """
- ticks_loc_angle = []
- ticklabels_loc_angle_label = []
-
- tick_add_angle = self._tick_add_angle
- ticklabel_add_angle = self._ticklabel_add_angle
-
- for loc, angle_normal, angle_tangent, label in tick_iter:
- angle_label = angle_tangent - 90
- angle_label += ticklabel_add_angle
-
- if np.cos((angle_label - angle_normal)/180.*np.pi) < 0.:
- angle_tick = angle_normal
- else:
- angle_tick = angle_normal + 180
-
- ticks_loc_angle.append([loc, angle_tick])
- ticklabels_loc_angle_label.append([loc, angle_label, label])
-
- return ticks_loc_angle, ticklabels_loc_angle_label
-
-
- def _update_ticks(self, renderer):
-
-
- # set extra pad for major and minor ticklabels:
- # use ticksize of majorticks even for minor ticks. not clear what is best.
-
- dpi_cor = renderer.points_to_pixels(1.)
- if self.major_ticks.get_visible() and self.major_ticks.get_tick_out():
- self.major_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- self.minor_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- else:
- self.major_ticklabels._set_external_pad(0)
- self.minor_ticklabels._set_external_pad(0)
-
-
- majortick_iter, minortick_iter = \
- self._axis_artist_helper.get_tick_iterators(self.axes)
-
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(majortick_iter)
-
- self.major_ticks.set_locs_angles(tick_loc_angle)
- self.major_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- #self.major_ticks.draw(renderer)
- #self.major_ticklabels.draw(renderer)
-
-
- # minor ticks
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(minortick_iter)
-
- self.minor_ticks.set_locs_angles(tick_loc_angle)
- self.minor_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- #self.minor_ticks.draw(renderer)
- #self.minor_ticklabels.draw(renderer)
-
-
- #if (self.major_ticklabels.get_visible() or self.minor_ticklabels.get_visible()):
- # self._draw_offsetText(renderer)
-
- return self.major_ticklabels.get_window_extents(renderer)
-
-
- def _draw_ticks(self, renderer):
-
- extents = self._update_ticks(renderer)
-
- self.major_ticks.draw(renderer)
- self.major_ticklabels.draw(renderer)
-
- self.minor_ticks.draw(renderer)
- self.minor_ticklabels.draw(renderer)
-
-
- if (self.major_ticklabels.get_visible() or self.minor_ticklabels.get_visible()):
- self._draw_offsetText(renderer)
-
- return extents
-
- def _draw_ticks2(self, renderer):
-
-
- # set extra pad for major and minor ticklabels:
- # use ticksize of majorticks even for minor ticks. not clear what is best.
-
- dpi_cor = renderer.points_to_pixels(1.)
- if self.major_ticks.get_visible() and self.major_ticks.get_tick_out():
- self.major_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- self.minor_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- else:
- self.major_ticklabels._set_external_pad(0)
- self.minor_ticklabels._set_external_pad(0)
-
-
- majortick_iter, minortick_iter = \
- self._axis_artist_helper.get_tick_iterators(self.axes)
-
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(majortick_iter)
-
- self.major_ticks.set_locs_angles(tick_loc_angle)
- self.major_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- self.major_ticks.draw(renderer)
- self.major_ticklabels.draw(renderer)
-
-
- # minor ticks
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(minortick_iter)
-
- self.minor_ticks.set_locs_angles(tick_loc_angle)
- self.minor_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- self.minor_ticks.draw(renderer)
- self.minor_ticklabels.draw(renderer)
-
-
- if (self.major_ticklabels.get_visible() or self.minor_ticklabels.get_visible()):
- self._draw_offsetText(renderer)
-
- return self.major_ticklabels.get_window_extents(renderer)
-
-
-
-
- _offsetText_pos = dict(left=(0, 1, "bottom", "right"),
- right=(1, 1, "bottom", "left"),
- bottom=(1, 0, "top", "right"),
- top=(1, 1, "bottom", "right"))
-
- def _init_offsetText(self, direction):
-
- x,y,va,ha = self._offsetText_pos[direction]
-
- self.offsetText = mtext.Annotation("",
- xy=(x,y), xycoords="axes fraction",
- xytext=(0,0), textcoords="offset points",
- #fontproperties = fp,
- color = rcParams['xtick.color'],
- verticalalignment=va,
- horizontalalignment=ha,
- )
- self.offsetText.set_transform(IdentityTransform())
- self.axes._set_artist_props(self.offsetText)
-
-
- def _update_offsetText(self):
- self.offsetText.set_text( self.axis.major.formatter.get_offset() )
- self.offsetText.set_size(self.major_ticklabels.get_size())
- offset = self.major_ticklabels.get_pad() + self.major_ticklabels.get_size() + 2.
- self.offsetText.xyann= (0, offset)
-
-
- def _draw_offsetText(self, renderer):
- self._update_offsetText()
- self.offsetText.draw(renderer)
-
-
-
- def _init_label(self, **kw):
- # x in axes coords, y in display coords (to be updated at draw
- # time by _update_label_positions)
-
- labelsize = kw.get("labelsize",
- rcParams['axes.labelsize'])
- #labelcolor = kw.get("labelcolor",
- # rcParams['axes.labelcolor'])
- fontprops = font_manager.FontProperties(
- size=labelsize,
- weight=rcParams['axes.labelweight'])
- textprops = dict(fontproperties = fontprops)
- #color = labelcolor)
-
- tr = self._axis_artist_helper.get_axislabel_transform(self.axes) \
- + self.offset_transform
-
- self.label = AxisLabel(0, 0, "__from_axes__",
- color = "auto", #rcParams['axes.labelcolor'],
- fontproperties=fontprops,
- axis=self.axis,
- transform=tr,
- axis_direction=self._axis_direction,
- )
-
- self.label.set_figure(self.axes.figure)
-
- labelpad = kw.get("labelpad", 5)
- self.label.set_pad(labelpad)
-
-
- def _update_label(self, renderer):
-
- if not self.label.get_visible():
- return
-
- fontprops = font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight'])
-
- #pad_points = self.major_tick_pad
-
- #if abs(self._ticklabel_add_angle - self._axislabel_add_angle)%360 > 90:
- if self._ticklabel_add_angle != self._axislabel_add_angle:
- if (self.major_ticks.get_visible() and not self.major_ticks.get_tick_out()) \
- or \
- (self.minor_ticks.get_visible() and not self.major_ticks.get_tick_out()):
- axislabel_pad = self.major_ticks._ticksize
- else:
- axislabel_pad = 0
- else:
- axislabel_pad = max(self.major_ticklabels._axislabel_pad,
- self.minor_ticklabels._axislabel_pad)
-
-
- #label_offset = axislabel_pad + self.LABELPAD
-
- #self.label._set_offset_radius(label_offset)
- self.label._set_external_pad(axislabel_pad)
-
- xy, angle_tangent = self._axis_artist_helper.get_axislabel_pos_angle(self.axes)
- if xy is None: return
-
- angle_label = angle_tangent - 90
-
-
- x, y = xy
- self.label._set_ref_angle(angle_label+self._axislabel_add_angle)
- self.label.set(x=x, y=y)
-
-
- def _draw_label(self, renderer):
- self._update_label(renderer)
- self.label.draw(renderer)
-
- def _draw_label2(self, renderer):
-
- if not self.label.get_visible():
- return
-
- fontprops = font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight'])
-
- #pad_points = self.major_tick_pad
-
- #if abs(self._ticklabel_add_angle - self._axislabel_add_angle)%360 > 90:
- if self._ticklabel_add_angle != self._axislabel_add_angle:
- if (self.major_ticks.get_visible() and not self.major_ticks.get_tick_out()) \
- or \
- (self.minor_ticks.get_visible() and not self.major_ticks.get_tick_out()):
- axislabel_pad = self.major_ticks._ticksize
- else:
- axislabel_pad = 0
- else:
- axislabel_pad = max(self.major_ticklabels._axislabel_pad,
- self.minor_ticklabels._axislabel_pad)
-
- #label_offset = axislabel_pad + self.LABELPAD
-
- #self.label._set_offset_radius(label_offset)
- self.label._set_external_pad(axislabel_pad)
-
- xy, angle_tangent = self._axis_artist_helper.get_axislabel_pos_angle(self.axes)
- if xy is None: return
-
- angle_label = angle_tangent - 90
-
- x, y = xy
- self.label._set_ref_angle(angle_label+self._axislabel_add_angle)
- self.label.set(x=x, y=y)
- self.label.draw(renderer)
-
-
-
- def set_label(self, s):
- self.label.set_text(s)
-
-
-
- def get_tightbbox(self, renderer):
- if not self.get_visible(): return
-
- self._axis_artist_helper.update_lim(self.axes)
-
- dpi_cor = renderer.points_to_pixels(1.)
- self.dpi_transform.clear().scale(dpi_cor, dpi_cor)
-
-
- bb = []
-
- self._update_ticks(renderer)
-
- #if self.major_ticklabels.get_visible():
- bb.extend(self.major_ticklabels.get_window_extents(renderer))
- #if self.minor_ticklabels.get_visible():
- bb.extend(self.minor_ticklabels.get_window_extents(renderer))
-
-
- self._update_label(renderer)
-
- #if self.label.get_visible():
- bb.append(self.label.get_window_extent(renderer))
- bb.append(self.offsetText.get_window_extent(renderer))
-
- bb = [b for b in bb if b and (b.width!=0 or b.height!=0)]
- if bb:
- _bbox = Bbox.union(bb)
- return _bbox
- else:
- return None
-
- #self._draw_line(renderer)
-
- #self._draw_ticks(renderer)
-
- #self._draw_offsetText(renderer)
- #self._draw_label(renderer)
-
-
-
- @allow_rasterization
- def draw(self, renderer):
- 'Draw the axis lines, tick lines and labels'
-
- if not self.get_visible(): return
-
- renderer.open_group(__name__)
-
- self._axis_artist_helper.update_lim(self.axes)
-
- dpi_cor = renderer.points_to_pixels(1.)
- self.dpi_transform.clear().scale(dpi_cor, dpi_cor)
-
-
- self._draw_ticks(renderer)
-
- self._draw_line(renderer)
-
- #self._draw_offsetText(renderer)
- self._draw_label(renderer)
-
- renderer.close_group(__name__)
-
- #def get_ticklabel_extents(self, renderer):
- # pass
-
- def toggle(self, all=None, ticks=None, ticklabels=None, label=None):
- """
- Toggle visibility of ticks, ticklabels, and (axis) label.
- To turn all off, ::
-
- axis.toggle(all=False)
-
- To turn all off but ticks on ::
-
- axis.toggle(all=False, ticks=True)
-
- To turn all on but (axis) label off ::
-
- axis.toggle(all=True, label=False))
-
- """
- if all:
- _ticks, _ticklabels, _label = True, True, True
- elif all is not None:
- _ticks, _ticklabels, _label = False, False, False
- else:
- _ticks, _ticklabels, _label = None, None, None
-
- if ticks is not None:
- _ticks = ticks
- if ticklabels is not None:
- _ticklabels = ticklabels
- if label is not None:
- _label = label
-
- if _ticks is not None:
- self.major_ticks.set_visible(_ticks)
- self.minor_ticks.set_visible(_ticks)
- if _ticklabels is not None:
- self.major_ticklabels.set_visible(_ticklabels)
- self.minor_ticklabels.set_visible(_ticklabels)
- if _label is not None:
- self.label.set_visible(_label)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py
deleted file mode 100644
index 876f5fe1898..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py
+++ /dev/null
@@ -1,168 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.patches import _Style, FancyArrowPatch
-from matplotlib.transforms import IdentityTransform
-from matplotlib.path import Path
-import numpy as np
-
-class _FancyAxislineStyle(object):
- class SimpleArrow(FancyArrowPatch):
- """
- The artist class that will be returned for SimpleArrow style.
- """
- _ARROW_STYLE = "->"
-
- def __init__(self, axis_artist, line_path, transform,
- line_mutation_scale):
- self._axis_artist = axis_artist
- self._line_transform = transform
- self._line_path = line_path
- self._line_mutation_scale = line_mutation_scale
-
- FancyArrowPatch.__init__(self,
- path=self._line_path,
- arrowstyle=self._ARROW_STYLE,
- arrow_transmuter=None,
- patchA=None,
- patchB=None,
- shrinkA=0.,
- shrinkB=0.,
- mutation_scale=line_mutation_scale,
- mutation_aspect=None,
- transform=IdentityTransform(),
- )
-
- def set_line_mutation_scale(self, scale):
- self.set_mutation_scale(scale*self._line_mutation_scale)
-
- def _extend_path(self, path, mutation_size=10):
- """
- Extend the path to make a room for drawing arrow.
- """
- from matplotlib.bezier import get_cos_sin
-
- x0, y0 = path.vertices[-2]
- x1, y1 = path.vertices[-1]
- cost, sint = get_cos_sin(x0, y0, x1, y1)
-
- d = mutation_size * 1.
- x2, y2 = x1 + cost*d, y1+sint*d
-
- if path.codes is None:
- _path = Path(np.concatenate([path.vertices, [[x2, y2]]]))
- else:
- _path = Path(np.concatenate([path.vertices, [[x2, y2]]]),
- np.concatenate([path.codes, [Path.LINETO]]))
-
- return _path
-
- def set_path(self, path):
- self._line_path = path
-
- def draw(self, renderer):
- """
- Draw the axis line.
- 1) transform the path to the display coordinate.
- 2) extend the path to make a room for arrow
- 3) update the path of the FancyArrowPatch.
- 4) draw
- """
- path_in_disp = self._line_transform.transform_path(self._line_path)
- mutation_size = self.get_mutation_scale() #line_mutation_scale()
- extented_path = self._extend_path(path_in_disp,
- mutation_size=mutation_size)
-
- self._path_original = extented_path
- FancyArrowPatch.draw(self, renderer)
-
- class FilledArrow(SimpleArrow):
- """
- The artist class that will be returned for SimpleArrow style.
- """
- _ARROW_STYLE = "-|>"
-
-
-class AxislineStyle(_Style):
- """
- :class:`AxislineStyle` is a container class which defines style classes
- for AxisArtists.
-
- An instance of any axisline style class is an callable object,
- whose call signature is ::
-
- __call__(self, axis_artist, path, transform)
-
- When called, this should return a mpl artist with following
- methods implemented. ::
-
- def set_path(self, path):
- # set the path for axisline.
-
- def set_line_mutation_scale(self, scale):
- # set the scale
-
- def draw(self, renderer):
- # draw
-
-
- """
-
- _style_list = {}
-
-
- class _Base(object):
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
-
- def __init__(self):
- """
- initialization.
- """
- super(AxislineStyle._Base, self).__init__()
-
-
-
-
- def __call__(self, axis_artist, transform):
- """
- Given the AxisArtist instance, and transform for the path
- (set_path method), return the mpl artist for drawing the axis line.
- """
-
- return self.new_line(axis_artist, transform)
-
-
- class SimpleArrow(_Base):
- """
- A simple arrow.
- """
-
- ArrowAxisClass = _FancyAxislineStyle.SimpleArrow
-
- def __init__(self, size=1):
- """
- *size*
- size of the arrow as a fraction of the ticklabel size.
- """
-
- self.size = size
- super(AxislineStyle.SimpleArrow, self).__init__()
-
- def new_line(self, axis_artist, transform):
-
- linepath = Path([(0,0), (0, 1)])
- axisline = self.ArrowAxisClass(axis_artist, linepath, transform,
- line_mutation_scale=self.size)
- return axisline
-
-
- _style_list["->"] = SimpleArrow
-
- class FilledArrow(SimpleArrow):
- ArrowAxisClass = _FancyAxislineStyle.FilledArrow
-
- _style_list["-|>"] = FilledArrow
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py
deleted file mode 100644
index 6182608cc5b..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py
+++ /dev/null
@@ -1,828 +0,0 @@
-"""
-Axislines includes modified implementation of the Axes class. The
-biggest difference is that the artists responsible for drawing the axis spine,
-ticks, ticklabels and axis labels are separated out from mpl's Axis
-class. Originally, this change was motivated to support curvilinear
-grid. Here are a few reasons that I came up with a new axes class:
-
-
- * "top" and "bottom" x-axis (or "left" and "right" y-axis) can have
- different ticks (tick locations and labels). This is not possible
- with the current mpl, although some twin axes trick can help.
-
- * Curvilinear grid.
-
- * angled ticks.
-
-In the new axes class, xaxis and yaxis is set to not visible by
-default, and new set of artist (AxisArtist) are defined to draw axis
-line, ticks, ticklabels and axis label. Axes.axis attribute serves as
-a dictionary of these artists, i.e., ax.axis["left"] is a AxisArtist
-instance responsible to draw left y-axis. The default Axes.axis contains
-"bottom", "left", "top" and "right".
-
-AxisArtist can be considered as a container artist and
-has following children artists which will draw ticks, labels, etc.
-
- * line
- * major_ticks, major_ticklabels
- * minor_ticks, minor_ticklabels
- * offsetText
- * label
-
-Note that these are separate artists from Axis class of the
-original mpl, thus most of tick-related command in the original mpl
-won't work, although some effort has made to work with. For example,
-color and markerwidth of the ax.axis["bottom"].major_ticks will follow
-those of Axes.xaxis unless explicitly specified.
-
-In addition to AxisArtist, the Axes will have *gridlines* attribute,
-which obviously draws grid lines. The gridlines needs to be separated
-from the axis as some gridlines can never pass any axis.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import warnings
-
-import numpy as np
-
-from matplotlib import rcParams
-import matplotlib.artist as martist
-import matplotlib.axes as maxes
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox
-from .axisline_style import AxislineStyle
-from .axis_artist import AxisArtist, GridlinesCollection
-
-
-class AxisArtistHelper(object):
- """
- AxisArtistHelper should define
- following method with given APIs. Note that the first axes argument
- will be axes attribute of the caller artist.::
-
-
- # LINE (spinal line?)
-
- def get_line(self, axes):
- # path : Path
- return path
-
- def get_line_transform(self, axes):
- # ...
- # trans : transform
- return trans
-
- # LABEL
-
- def get_label_pos(self, axes):
- # x, y : position
- return (x, y), trans
-
-
- def get_label_offset_transform(self, \
- axes,
- pad_points, fontprops, renderer,
- bboxes,
- ):
- # va : vertical alignment
- # ha : horizontal alignment
- # a : angle
- return trans, va, ha, a
-
- # TICK
-
- def get_tick_transform(self, axes):
- return trans
-
- def get_tick_iterators(self, axes):
- # iter : iterable object that yields (c, angle, l) where
- # c, angle, l is position, tick angle, and label
-
- return iter_major, iter_minor
-
-
- """
-
- class _Base(object):
- """
- Base class for axis helper.
- """
- def __init__(self):
- """
- """
- self.delta1, self.delta2 = 0.00001, 0.00001
-
- def update_lim(self, axes):
- pass
-
-
- class Fixed(_Base):
- """
- Helper class for a fixed (in the axes coordinate) axis.
- """
-
- _default_passthru_pt = dict(left=(0, 0),
- right=(1, 0),
- bottom=(0, 0),
- top=(0, 1))
-
- def __init__(self,
- loc, nth_coord=None,
- ):
- """
- nth_coord = along which coordinate value varies
- in 2d, nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- self._loc = loc
-
- if loc not in ["left", "right", "bottom", "top"]:
- raise ValueError("%s" % loc)
-
- if nth_coord is None:
- if loc in ["left", "right"]:
- nth_coord = 1
- elif loc in ["bottom", "top"]:
- nth_coord = 0
-
- self.nth_coord = nth_coord
-
- super(AxisArtistHelper.Fixed, self).__init__()
-
- self.passthru_pt = self._default_passthru_pt[loc]
-
-
-
- _verts = np.array([[0., 0.],
- [1., 1.]])
- fixed_coord = 1-nth_coord
- _verts[:,fixed_coord] = self.passthru_pt[fixed_coord]
-
- # axis line in transAxes
- self._path = Path(_verts)
-
-
- def get_nth_coord(self):
- return self.nth_coord
-
- # LINE
-
- def get_line(self, axes):
- return self._path
-
- def get_line_transform(self, axes):
- return axes.transAxes
-
- # LABEL
-
- def get_axislabel_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_pos_angle(self, axes):
- """
- label reference position in transAxes.
-
- get_label_transform() returns a transform of (transAxes+offset)
- """
- loc = self._loc
- pos, angle_tangent = dict(left=((0., 0.5), 90),
- right=((1., 0.5), 90),
- bottom=((0.5, 0.), 0),
- top=((0.5, 1.), 0))[loc]
-
- return pos, angle_tangent
-
-
-
- # TICK
-
- def get_tick_transform(self, axes):
- trans_tick = [axes.get_xaxis_transform(),
- axes.get_yaxis_transform()][self.nth_coord]
-
- return trans_tick
-
-
- class Floating(_Base):
- def __init__(self, nth_coord,
- value):
-
- self.nth_coord = nth_coord
-
- self._value = value
-
- super(AxisArtistHelper.Floating,
- self).__init__()
-
-
- def get_nth_coord(self):
- return self.nth_coord
-
- def get_line(self, axes):
- raise RuntimeError("get_line method should be defined by the derived class")
-
-
-
-
-class AxisArtistHelperRectlinear(object):
-
- class Fixed(AxisArtistHelper.Fixed):
-
- def __init__(self, axes, loc, nth_coord=None):
- """
- nth_coord = along which coordinate value varies
- in 2d, nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
- super(AxisArtistHelperRectlinear.Fixed, self).__init__(
- loc, nth_coord)
- self.axis = [axes.xaxis, axes.yaxis][self.nth_coord]
-
- # TICK
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
-
- loc = self._loc
-
- if loc in ["bottom", "top"]:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- major = self.axis.major
- majorLocs = major.locator()
- major.formatter.set_locs(majorLocs)
- majorLabels = [major.formatter(val, i) for i, val in enumerate(majorLocs)]
-
- minor = self.axis.minor
- minorLocs = minor.locator()
- minor.formatter.set_locs(minorLocs)
- minorLabels = [minor.formatter(val, i) for i, val in enumerate(minorLocs)]
-
- trans_tick = self.get_tick_transform(axes)
-
- tr2ax = trans_tick + axes.transAxes.inverted()
-
- def _f(locs, labels):
- for x, l in zip(locs, labels):
-
- c = list(self.passthru_pt) # copy
- c[self.nth_coord] = x
-
- # check if the tick point is inside axes
- c2 = tr2ax.transform_point(c)
- #delta=0.00001
- if 0. -self.delta1<= c2[self.nth_coord] <= 1.+self.delta2:
- yield c, angle_normal, angle_tangent, l
-
- return _f(majorLocs, majorLabels), _f(minorLocs, minorLabels)
-
-
-
- class Floating(AxisArtistHelper.Floating):
- def __init__(self, axes, nth_coord,
- passingthrough_point, axis_direction="bottom"):
- super(AxisArtistHelperRectlinear.Floating, self).__init__(
- nth_coord, passingthrough_point)
- self._axis_direction = axis_direction
- self.axis = [axes.xaxis, axes.yaxis][self.nth_coord]
-
- def get_line(self, axes):
- _verts = np.array([[0., 0.],
- [1., 1.]])
-
- fixed_coord = 1-self.nth_coord
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([self._value,
- self._value])
- _verts[:,fixed_coord] = p[fixed_coord]
-
- return Path(_verts)
-
- def get_line_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_pos_angle(self, axes):
- """
- label reference position in transAxes.
-
- get_label_transform() returns a transform of (transAxes+offset)
- """
- loc = self._axis_direction
- #angle = dict(left=0,
- # right=0,
- # bottom=.5*np.pi,
- # top=.5*np.pi)[loc]
-
- if self.nth_coord == 0:
- angle = 0
- else:
- angle = 90
-
- _verts = [0.5, 0.5]
-
- fixed_coord = 1-self.nth_coord
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([self._value,
- self._value])
- _verts[fixed_coord] = p[fixed_coord]
- if not (0. <= _verts[fixed_coord] <= 1.):
- return None, None
- else:
- return _verts, angle
-
-
-
- def get_tick_transform(self, axes):
- return axes.transData
-
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
-
- loc = self._axis_direction
-
- if loc in ["bottom", "top"]:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- if self.nth_coord == 0:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- #angle = 90 - 90 * self.nth_coord
-
- major = self.axis.major
- majorLocs = major.locator()
- major.formatter.set_locs(majorLocs)
- majorLabels = [major.formatter(val, i) for i, val in enumerate(majorLocs)]
-
- minor = self.axis.minor
- minorLocs = minor.locator()
- minor.formatter.set_locs(minorLocs)
- minorLabels = [minor.formatter(val, i) for i, val in enumerate(minorLocs)]
-
- tr2ax = axes.transData + axes.transAxes.inverted()
-
- def _f(locs, labels):
- for x, l in zip(locs, labels):
-
- c = [self._value, self._value]
- c[self.nth_coord] = x
- c1, c2 = tr2ax.transform_point(c)
- if 0. <= c1 <= 1. and 0. <= c2 <= 1.:
- if 0. - self.delta1 <= [c1, c2][self.nth_coord] <= 1. + self.delta2:
- yield c, angle_normal, angle_tangent, l
-
- return _f(majorLocs, majorLabels), _f(minorLocs, minorLabels)
-
-
-
-
-
-class GridHelperBase(object):
-
- def __init__(self):
- self._force_update = True
- self._old_limits = None
- super(GridHelperBase, self).__init__()
-
-
- def update_lim(self, axes):
- x1, x2 = axes.get_xlim()
- y1, y2 = axes.get_ylim()
-
- if self._force_update or self._old_limits != (x1, x2, y1, y2):
- self._update(x1, x2, y1, y2)
- self._force_update = False
- self._old_limits = (x1, x2, y1, y2)
-
-
- def _update(self, x1, x2, y1, y2):
- pass
-
-
- def invalidate(self):
- self._force_update = True
-
- def valid(self):
- return not self._force_update
-
-
- def get_gridlines(self, which, axis):
- """
- Return list of grid lines as a list of paths (list of points).
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
- """
- return []
-
- def new_gridlines(self, ax):
- """
- Create and return a new GridlineCollection instance.
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
-
- """
- gridlines = GridlinesCollection(None, transform=ax.transData,
- colors=rcParams['grid.color'],
- linestyles=rcParams['grid.linestyle'],
- linewidths=rcParams['grid.linewidth'])
- ax._set_artist_props(gridlines)
- gridlines.set_grid_helper(self)
-
- ax.axes._set_artist_props(gridlines)
- # gridlines.set_clip_path(self.axes.patch)
- # set_clip_path need to be deferred after Axes.cla is completed.
- # It is done inside the cla.
-
- return gridlines
-
-
-class GridHelperRectlinear(GridHelperBase):
-
-
- def __init__(self, axes):
-
- super(GridHelperRectlinear, self).__init__()
- self.axes = axes
-
-
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None,
- ):
-
- if axes is None:
- warnings.warn("'new_fixed_axis' explicitly requires the axes keyword.")
- axes = self.axes
-
- _helper = AxisArtistHelperRectlinear.Fixed(axes, loc, nth_coord)
-
- if axis_direction is None:
- axis_direction = loc
- axisline = AxisArtist(axes, _helper, offset=offset,
- axis_direction=axis_direction,
- )
-
- return axisline
-
-
- def new_floating_axis(self, nth_coord, value,
- axis_direction="bottom",
- axes=None,
- ):
-
- if axes is None:
- warnings.warn(
- "'new_floating_axis' explicitly requires the axes keyword.")
- axes = self.axes
-
- passthrough_point = (value, value)
- transform = axes.transData
-
- _helper = AxisArtistHelperRectlinear.Floating(
- axes, nth_coord, value, axis_direction)
-
- axisline = AxisArtist(axes, _helper)
-
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- return axisline
-
-
- def get_gridlines(self, which="major", axis="both"):
- """
- return list of gridline coordinates in data coordinates.
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
- """
-
- gridlines = []
-
-
- if axis in ["both", "x"]:
- locs = []
- y1, y2 = self.axes.get_ylim()
- #if self.axes.xaxis._gridOnMajor:
- if which in ["both", "major"]:
- locs.extend(self.axes.xaxis.major.locator())
- #if self.axes.xaxis._gridOnMinor:
- if which in ["both", "minor"]:
- locs.extend(self.axes.xaxis.minor.locator())
-
- for x in locs:
- gridlines.append([[x, x], [y1, y2]])
-
-
- if axis in ["both", "y"]:
- x1, x2 = self.axes.get_xlim()
- locs = []
- if self.axes.yaxis._gridOnMajor:
- #if which in ["both", "major"]:
- locs.extend(self.axes.yaxis.major.locator())
- if self.axes.yaxis._gridOnMinor:
- #if which in ["both", "minor"]:
- locs.extend(self.axes.yaxis.minor.locator())
-
- for y in locs:
- gridlines.append([[x1, x2], [y, y]])
-
- return gridlines
-
-
-
-
-
-
-class SimpleChainedObjects(object):
- def __init__(self, objects):
- self._objects = objects
-
- def __getattr__(self, k):
- _a = SimpleChainedObjects([getattr(a, k) for a in self._objects])
- return _a
-
- def __call__(self, *kl, **kwargs):
- for m in self._objects:
- m(*kl, **kwargs)
-
-
-class Axes(maxes.Axes):
-
- class AxisDict(dict):
- def __init__(self, axes):
- self.axes = axes
- super(Axes.AxisDict, self).__init__()
-
- def __getitem__(self, k):
- if isinstance(k, tuple):
- r = SimpleChainedObjects([dict.__getitem__(self, k1) for k1 in k])
- return r
- elif isinstance(k, slice):
- if k.start == None and k.stop == None and k.step == None:
- r = SimpleChainedObjects(list(six.itervalues(self)))
- return r
- else:
- raise ValueError("Unsupported slice")
- else:
- return dict.__getitem__(self, k)
-
- def __call__(self, *v, **kwargs):
- return maxes.Axes.axis(self.axes, *v, **kwargs)
-
-
- def __init__(self, *kl, **kw):
-
-
- helper = kw.pop("grid_helper", None)
-
- self._axisline_on = True
-
- if helper:
- self._grid_helper = helper
- else:
- self._grid_helper = GridHelperRectlinear(self)
-
- super(Axes, self).__init__(*kl, **kw)
-
- self.toggle_axisline(True)
-
-
- def toggle_axisline(self, b=None):
- if b is None:
- b = not self._axisline_on
- if b:
- self._axisline_on = True
- for s in self.spines.values():
- s.set_visible(False)
- self.xaxis.set_visible(False)
- self.yaxis.set_visible(False)
- else:
- self._axisline_on = False
- for s in self.spines.values():
- s.set_visible(True)
- self.xaxis.set_visible(True)
- self.yaxis.set_visible(True)
-
-
- def _init_axis(self):
- super(Axes, self)._init_axis()
-
-
- def _init_axis_artists(self, axes=None):
- if axes is None:
- axes = self
-
- self._axislines = self.AxisDict(self)
- new_fixed_axis = self.get_grid_helper().new_fixed_axis
- for loc in ["bottom", "top", "left", "right"]:
- self._axislines[loc] = new_fixed_axis(loc=loc, axes=axes,
- axis_direction=loc)
-
- for axisline in [self._axislines["top"], self._axislines["right"]]:
- axisline.label.set_visible(False)
- axisline.major_ticklabels.set_visible(False)
- axisline.minor_ticklabels.set_visible(False)
-
- @property
- def axis(self):
- return self._axislines
-
- def new_gridlines(self, grid_helper=None):
- """
- Create and return a new GridlineCollection instance.
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
-
- """
- if grid_helper is None:
- grid_helper = self.get_grid_helper()
-
- gridlines = grid_helper.new_gridlines(self)
-
- return gridlines
-
-
- def _init_gridlines(self, grid_helper=None):
- # It is done inside the cla.
- gridlines = self.new_gridlines(grid_helper)
-
- self.gridlines = gridlines
-
- def cla(self):
- # gridlines need to b created before cla() since cla calls grid()
-
- self._init_gridlines()
- super(Axes, self).cla()
-
- # the clip_path should be set after Axes.cla() since that's
- # when a patch is created.
- self.gridlines.set_clip_path(self.axes.patch)
-
- self._init_axis_artists()
-
- def get_grid_helper(self):
- return self._grid_helper
-
-
- def grid(self, b=None, which='major', axis="both", **kwargs):
- """
- Toggle the gridlines, and optionally set the properties of the lines.
- """
- # their are some discrepancy between the behavior of grid in
- # axes_grid and the original mpl's grid, because axes_grid
- # explicitly set the visibility of the gridlines.
-
- super(Axes, self).grid(b, which=which, axis=axis, **kwargs)
- if not self._axisline_on:
- return
-
- if b is None:
-
- if self.axes.xaxis._gridOnMinor or self.axes.xaxis._gridOnMajor or \
- self.axes.yaxis._gridOnMinor or self.axes.yaxis._gridOnMajor:
- b=True
- else:
- b=False
-
- self.gridlines.set_which(which)
- self.gridlines.set_axis(axis)
- self.gridlines.set_visible(b)
-
- if len(kwargs):
- martist.setp(self.gridlines, **kwargs)
-
- def get_children(self):
- if self._axisline_on:
- children = list(six.itervalues(self._axislines)) + [self.gridlines]
- else:
- children = []
- children.extend(super(Axes, self).get_children())
- return children
-
- def invalidate_grid_helper(self):
- self._grid_helper.invalidate()
-
-
- def new_fixed_axis(self, loc, offset=None):
- gh = self.get_grid_helper()
- axis = gh.new_fixed_axis(loc,
- nth_coord=None,
- axis_direction=None,
- offset=offset,
- axes=self,
- )
- return axis
-
-
- def new_floating_axis(self, nth_coord, value,
- axis_direction="bottom",
- ):
- gh = self.get_grid_helper()
- axis = gh.new_floating_axis(nth_coord, value,
- axis_direction=axis_direction,
- axes=self)
- return axis
-
-
-
- def draw(self, renderer, inframe=False):
-
- if not self._axisline_on:
- super(Axes, self).draw(renderer, inframe)
- return
-
- orig_artists = self.artists
- self.artists = self.artists + list(self._axislines.values()) + [self.gridlines]
-
- super(Axes, self).draw(renderer, inframe)
-
- self.artists = orig_artists
-
-
- def get_tightbbox(self, renderer, call_axes_locator=True):
-
- bb0 = super(Axes, self).get_tightbbox(renderer, call_axes_locator)
-
- if not self._axisline_on:
- return bb0
-
- bb = [bb0]
-
- for axisline in list(six.itervalues(self._axislines)):
- if not axisline.get_visible():
- continue
-
- bb.append(axisline.get_tightbbox(renderer))
- # if axisline.label.get_visible():
- # bb.append(axisline.label.get_window_extent(renderer))
-
-
- # if axisline.major_ticklabels.get_visible():
- # bb.extend(axisline.major_ticklabels.get_window_extents(renderer))
- # if axisline.minor_ticklabels.get_visible():
- # bb.extend(axisline.minor_ticklabels.get_window_extents(renderer))
- # if axisline.major_ticklabels.get_visible() or \
- # axisline.minor_ticklabels.get_visible():
- # bb.append(axisline.offsetText.get_window_extent(renderer))
-
- #bb.extend([c.get_window_extent(renderer) for c in artists \
- # if c.get_visible()])
-
- _bbox = Bbox.union([b for b in bb if b and (b.width!=0 or b.height!=0)])
-
- return _bbox
-
-
-
-
-Subplot = maxes.subplot_class_factory(Axes)
-
-class AxesZero(Axes):
- def __init__(self, *kl, **kw):
-
- super(AxesZero, self).__init__(*kl, **kw)
-
-
- def _init_axis_artists(self):
- super(AxesZero, self)._init_axis_artists()
-
- new_floating_axis = self._grid_helper.new_floating_axis
- xaxis_zero = new_floating_axis(nth_coord=0,
- value=0.,
- axis_direction="bottom",
- axes=self)
-
- xaxis_zero.line.set_clip_path(self.patch)
- xaxis_zero.set_visible(False)
- self._axislines["xzero"] = xaxis_zero
-
- yaxis_zero = new_floating_axis(nth_coord=1,
- value=0.,
- axis_direction="left",
- axes=self)
-
-
- yaxis_zero.line.set_clip_path(self.patch)
- yaxis_zero.set_visible(False)
- self._axislines["yzero"] = yaxis_zero
-
-SubplotZero = maxes.subplot_class_factory(AxesZero)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py
deleted file mode 100644
index 8507b09b075..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py
+++ /dev/null
@@ -1,135 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-import numpy as np
-from math import degrees
-import math
-import warnings
-
-def atan2(dy, dx):
- if dx == 0 and dy == 0:
- warnings.warn("dx and dy is 0")
- return 0
- else:
- return math.atan2(dy, dx)
-
-# FIXME : The current algorithm seems to return incorrect angle when the line
-# ends at the boundary.
-
-def clip(xlines, ylines, x0, clip="right", xdir=True, ydir=True):
-
- clipped_xlines = []
- clipped_ylines = []
-
- _pos_angles = []
-
- if xdir:
- xsign = 1
- else:
- xsign = -1
-
- if ydir:
- ysign = 1
- else:
- ysign = -1
-
-
- for x, y in zip(xlines, ylines):
-
- if clip in ["up", "right"]:
- b = (x < x0).astype("i")
- db = b[1:] - b[:-1]
- else:
- b = (x > x0).astype("i")
- db = b[1:] - b[:-1]
-
-
- if b[0]:
- ns = 0
- else:
- ns = -1
- segx, segy = [], []
- for (i,) in np.argwhere(db!=0):
- c = db[i]
- if c == -1:
- dx = (x0 - x[i])
- dy = (y[i+1] - y[i]) * (dx/ (x[i+1] - x[i]))
- y0 = y[i] + dy
- clipped_xlines.append(np.concatenate([segx, x[ns:i+1], [x0]]))
- clipped_ylines.append(np.concatenate([segy, y[ns:i+1], [y0]]))
- ns = -1
- segx, segy = [], []
-
- if dx == 0. and dy == 0:
- dx = x[i+1] - x[i]
- dy = y[i+1] - y[i]
-
- a = degrees(atan2(ysign*dy, xsign*dx))
- _pos_angles.append((x0, y0, a))
-
- elif c == 1:
- dx = (x0 - x[i])
- dy = (y[i+1] - y[i]) * (dx / (x[i+1] - x[i]))
- y0 = y[i] + dy
- segx, segy = [x0], [y0]
- ns = i+1
-
- if dx == 0. and dy == 0:
- dx = x[i+1] - x[i]
- dy = y[i+1] - y[i]
-
- a = degrees(atan2(ysign*dy, xsign*dx))
- _pos_angles.append((x0, y0, a))
-
- if ns != -1:
- clipped_xlines.append(np.concatenate([segx, x[ns:]]))
- clipped_ylines.append(np.concatenate([segy, y[ns:]]))
-
- #clipped_pos_angles.append(_pos_angles)
-
-
- return clipped_xlines, clipped_ylines, _pos_angles
-
-
-def clip_line_to_rect(xline, yline, bbox):
-
- x0, y0, x1, y1 = bbox.extents
-
- xdir = x1 > x0
- ydir = y1 > y0
-
- if x1 > x0:
- lx1, ly1, c_right_ = clip([xline], [yline], x1, clip="right", xdir=xdir, ydir=ydir)
- lx2, ly2, c_left_ = clip(lx1, ly1, x0, clip="left", xdir=xdir, ydir=ydir)
- else:
- lx1, ly1, c_right_ = clip([xline], [yline], x0, clip="right", xdir=xdir, ydir=ydir)
- lx2, ly2, c_left_ = clip(lx1, ly1, x1, clip="left", xdir=xdir, ydir=ydir)
-
- if y1 > y0:
- ly3, lx3, c_top_ = clip(ly2, lx2, y1, clip="right", xdir=ydir, ydir=xdir)
- ly4, lx4, c_bottom_ = clip(ly3, lx3, y0, clip="left", xdir=ydir, ydir=xdir)
- else:
- ly3, lx3, c_top_ = clip(ly2, lx2, y0, clip="right", xdir=ydir, ydir=xdir)
- ly4, lx4, c_bottom_ = clip(ly3, lx3, y1, clip="left", xdir=ydir, ydir=xdir)
-
-
- # lx1, ly1, c_right_ = clip([xline], [yline], x1, clip="right")
- # lx2, ly2, c_left_ = clip(lx1, ly1, x0, clip="left")
- # ly3, lx3, c_top_ = clip(ly2, lx2, y1, clip="right")
- # ly4, lx4, c_bottom_ = clip(ly3, lx3, y0, clip="left")
-
- #c_left = [((x, y), (a+90)%180-180) for (x, y, a) in c_left_ \
- # if bbox.containsy(y)]
- c_left = [((x, y), (a+90)%180-90) for (x, y, a) in c_left_
- if bbox.containsy(y)]
- c_bottom = [((x, y), (90 - a)%180) for (y, x, a) in c_bottom_
- if bbox.containsx(x)]
- c_right = [((x, y), (a+90)%180+90) for (x, y, a) in c_right_
- if bbox.containsy(y)]
- c_top = [((x, y), (90 - a)%180+180) for (y, x, a) in c_top_
- if bbox.containsx(x)]
-
- return list(zip(lx4, ly4)), [c_left, c_bottom, c_right, c_top]
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py
deleted file mode 100644
index 468413dbac4..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py
+++ /dev/null
@@ -1,544 +0,0 @@
-"""
-An experimental support for curvilinear grid.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-# TODO :
-# see if tick_iterator method can be simplified by reusing the parent method.
-
-import numpy as np
-
-from matplotlib.transforms import Affine2D, IdentityTransform
-from . import grid_helper_curvelinear
-from .axislines import AxisArtistHelper, GridHelperBase
-from .axis_artist import AxisArtist
-from .grid_finder import GridFinder
-
-
-class FloatingAxisArtistHelper(grid_helper_curvelinear.FloatingAxisArtistHelper):
- pass
-
-
-class FixedAxisArtistHelper(grid_helper_curvelinear.FloatingAxisArtistHelper):
-
- def __init__(self, grid_helper, side, nth_coord_ticks=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- value, nth_coord = grid_helper.get_data_boundary(side) # return v= 0 , nth=1, extremes of the other coordinate.
- super(FixedAxisArtistHelper, self).__init__(grid_helper,
- nth_coord,
- value,
- axis_direction=side,
- )
- #self.grid_helper = grid_helper
- if nth_coord_ticks is None:
- nth_coord_ticks = nth_coord
- self.nth_coord_ticks = nth_coord_ticks
-
- self.value = value
- self.grid_helper = grid_helper
- self._side = side
-
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- self.grid_info = self.grid_helper.grid_info
-
-
-
- def get_axislabel_pos_angle(self, axes):
-
- extremes = self.grid_info["extremes"]
-
- if self.nth_coord == 0:
- xx0 = self.value
- yy0 = (extremes[2]+extremes[3])/2.
- dxx, dyy = 0., abs(extremes[2]-extremes[3])/1000.
- elif self.nth_coord == 1:
- xx0 = (extremes[0]+extremes[1])/2.
- yy0 = self.value
- dxx, dyy = abs(extremes[0]-extremes[1])/1000., 0.
-
- grid_finder = self.grid_helper.grid_finder
- xx1, yy1 = grid_finder.transform_xy([xx0], [yy0])
-
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([xx1[0], yy1[0]])
-
-
- if (0. <= p[0] <= 1.) and (0. <= p[1] <= 1.):
- xx1c, yy1c = axes.transData.transform_point([xx1[0], yy1[0]])
- xx2, yy2 = grid_finder.transform_xy([xx0+dxx], [yy0+dyy])
- xx2c, yy2c = axes.transData.transform_point([xx2[0], yy2[0]])
-
- return (xx1c, yy1c), np.arctan2(yy2c-yy1c, xx2c-xx1c)/np.pi*180.
- else:
- return None, None
-
-
-
- def get_tick_transform(self, axes):
- return IdentityTransform() #axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label, (optionally) tick_label"""
-
-
- grid_finder = self.grid_helper.grid_finder
-
- lat_levs, lat_n, lat_factor = self.grid_info["lat_info"]
- lon_levs, lon_n, lon_factor = self.grid_info["lon_info"]
-
- lon_levs, lat_levs = np.asarray(lon_levs), np.asarray(lat_levs)
- if lat_factor is not None:
- yy0 = lat_levs / lat_factor
- dy = 0.001 / lat_factor
- else:
- yy0 = lat_levs
- dy = 0.001
-
- if lon_factor is not None:
- xx0 = lon_levs / lon_factor
- dx = 0.001 / lon_factor
- else:
- xx0 = lon_levs
- dx = 0.001
-
- _extremes = self.grid_helper._extremes
- xmin, xmax = sorted(_extremes[:2])
- ymin, ymax = sorted(_extremes[2:])
- if self.nth_coord == 0:
- mask = (ymin <= yy0) & (yy0 <= ymax)
- yy0 = yy0[mask]
- elif self.nth_coord == 1:
- mask = (xmin <= xx0) & (xx0 <= xmax)
- xx0 = xx0[mask]
-
- def transform_xy(x, y):
- x1, y1 = grid_finder.transform_xy(x, y)
- x2y2 = axes.transData.transform(np.array([x1, y1]).transpose())
- x2, y2 = x2y2.transpose()
- return x2, y2
-
- # find angles
- if self.nth_coord == 0:
- xx0 = np.empty_like(yy0)
- xx0.fill(self.value)
-
- #yy0_ = yy0.copy()
-
- xx1, yy1 = transform_xy(xx0, yy0)
-
- xx00 = xx0.astype(float, copy=True)
- xx00[xx0+dx>xmax] -= dx
- xx1a, yy1a = transform_xy(xx00, yy0)
- xx1b, yy1b = transform_xy(xx00+dx, yy0)
-
- yy00 = yy0.astype(float, copy=True)
- yy00[yy0+dy>ymax] -= dy
- xx2a, yy2a = transform_xy(xx0, yy00)
- xx2b, yy2b = transform_xy(xx0, yy00+dy)
-
- labels = self.grid_info["lat_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
- elif self.nth_coord == 1:
- yy0 = np.empty_like(xx0)
- yy0.fill(self.value)
-
- #xx0_ = xx0.copy()
- xx1, yy1 = transform_xy(xx0, yy0)
-
-
- yy00 = yy0.astype(float, copy=True)
- yy00[yy0+dy>ymax] -= dy
- xx1a, yy1a = transform_xy(xx0, yy00)
- xx1b, yy1b = transform_xy(xx0, yy00+dy)
-
- xx00 = xx0.astype(float, copy=True)
- xx00[xx0+dx>xmax] -= dx
- xx2a, yy2a = transform_xy(xx00, yy0)
- xx2b, yy2b = transform_xy(xx00+dx, yy0)
-
- labels = self.grid_info["lon_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
-
- def f1():
- dd = np.arctan2(yy1b-yy1a, xx1b-xx1a) # angle normal
- dd2 = np.arctan2(yy2b-yy2a, xx2b-xx2a) # angle tangent
- mm = ((yy1b-yy1a)==0.) & ((xx1b-xx1a)==0.) # mask where dd1 is not defined
- dd[mm] = dd2[mm] + np.pi / 2
-
- #dd += np.pi
- #dd = np.arctan2(xx2-xx1, angle_tangent-yy1)
- trans_tick = self.get_tick_transform(axes)
- tr2ax = trans_tick + axes.transAxes.inverted()
- for x, y, d, d2, lab in zip(xx1, yy1, dd, dd2, labels):
- c2 = tr2ax.transform_point((x, y))
- delta=0.00001
- if (0. -delta<= c2[0] <= 1.+delta) and \
- (0. -delta<= c2[1] <= 1.+delta):
- d1 = d/3.14159*180.
- d2 = d2/3.14159*180.
- #_mod = (d2-d1+180)%360
- #if _mod < 180:
- # d1 += 180
- ##_div, _mod = divmod(d2-d1, 360)
- yield [x, y], d1, d2, lab
- #, d2/3.14159*180.+da)
-
- return f1(), iter([])
-
- def get_line_transform(self, axes):
- return axes.transData
-
- def get_line(self, axes):
-
- self.update_lim(axes)
- from matplotlib.path import Path
- k, v = dict(left=("lon_lines0", 0),
- right=("lon_lines0", 1),
- bottom=("lat_lines0", 0),
- top=("lat_lines0", 1))[self._side]
-
- xx, yy = self.grid_info[k][v]
- return Path(np.column_stack([xx, yy]))
-
-
-
-from .grid_finder import ExtremeFinderSimple
-
-class ExtremeFinderFixed(ExtremeFinderSimple):
- def __init__(self, extremes):
- self._extremes = extremes
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- get extreme values.
-
- x1, y1, x2, y2 in image coordinates (0-based)
- nx, ny : number of division in each axis
- """
- #lon_min, lon_max, lat_min, lat_max = self._extremes
- return self._extremes
-
-
-
-class GridHelperCurveLinear(grid_helper_curvelinear.GridHelperCurveLinear):
-
- def __init__(self, aux_trans, extremes,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- aux_trans : a transform from the source (curved) coordinate to
- target (rectilinear) coordinate. An instance of MPL's Transform
- (inverse transform should be defined) or a tuple of two callable
- objects which defines the transform and its inverse. The callables
- need take two arguments of array of source coordinates and
- should return two target coordinates:
- e.g., *x2, y2 = trans(x1, y1)*
- """
-
- self._old_values = None
-
- self._extremes = extremes
- extreme_finder = ExtremeFinderFixed(extremes)
-
- super(GridHelperCurveLinear, self).__init__(aux_trans,
- extreme_finder,
- grid_locator1=grid_locator1,
- grid_locator2=grid_locator2,
- tick_formatter1=tick_formatter1,
- tick_formatter2=tick_formatter2)
-
-
- # def update_grid_finder(self, aux_trans=None, **kw):
-
- # if aux_trans is not None:
- # self.grid_finder.update_transform(aux_trans)
-
- # self.grid_finder.update(**kw)
- # self.invalidate()
-
-
- # def _update(self, x1, x2, y1, y2):
- # "bbox in 0-based image coordinates"
- # # update wcsgrid
-
- # if self.valid() and self._old_values == (x1, x2, y1, y2):
- # return
-
- # self._update_grid(x1, y1, x2, y2)
-
- # self._old_values = (x1, x2, y1, y2)
-
- # self._force_update = False
-
-
- def get_data_boundary(self, side):
- """
- return v= 0 , nth=1
- """
- lon1, lon2, lat1, lat2 = self._extremes
- return dict(left=(lon1, 0),
- right=(lon2, 0),
- bottom=(lat1, 1),
- top=(lat2, 1))[side]
-
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None):
-
- if axes is None:
- axes = self.axes
-
- if axis_direction is None:
- axis_direction = loc
-
- _helper = FixedAxisArtistHelper(self, loc,
- nth_coord_ticks=nth_coord)
-
-
- axisline = AxisArtist(axes, _helper, axis_direction=axis_direction)
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
-
-
- return axisline
-
-
- # new_floating_axis will inherit the grid_helper's extremes.
-
- # def new_floating_axis(self, nth_coord,
- # value,
- # axes=None,
- # axis_direction="bottom"
- # ):
-
- # axis = super(GridHelperCurveLinear,
- # self).new_floating_axis(nth_coord,
- # value, axes=axes,
- # axis_direction=axis_direction)
-
- # # set extreme values of the axis helper
- # if nth_coord == 1:
- # axis.get_helper().set_extremes(*self._extremes[:2])
- # elif nth_coord == 0:
- # axis.get_helper().set_extremes(*self._extremes[2:])
-
- # return axis
-
-
- def _update_grid(self, x1, y1, x2, y2):
-
- #self.grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2)
-
- if self.grid_info is None:
- self.grid_info = dict()
-
- grid_info = self.grid_info
-
- grid_finder = self.grid_finder
- extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy,
- x1, y1, x2, y2)
-
- lon_min, lon_max = sorted(extremes[:2])
- lat_min, lat_max = sorted(extremes[2:])
- lon_levs, lon_n, lon_factor = \
- grid_finder.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- grid_finder.grid_locator2(lat_min, lat_max)
- grid_info["extremes"] = lon_min, lon_max, lat_min, lat_max #extremes
-
- grid_info["lon_info"] = lon_levs, lon_n, lon_factor
- grid_info["lat_info"] = lat_levs, lat_n, lat_factor
-
- grid_info["lon_labels"] = grid_finder.tick_formatter1("bottom",
- lon_factor,
- lon_levs)
-
- grid_info["lat_labels"] = grid_finder.tick_formatter2("bottom",
- lat_factor,
- lat_levs)
-
- if lon_factor is None:
- lon_values = np.asarray(lon_levs[:lon_n])
- else:
- lon_values = np.asarray(lon_levs[:lon_n]/lon_factor)
- if lat_factor is None:
- lat_values = np.asarray(lat_levs[:lat_n])
- else:
- lat_values = np.asarray(lat_levs[:lat_n]/lat_factor)
-
- lon_values0 = lon_values[(lon_min<lon_values) & (lon_values<lon_max)]
- lat_values0 = lat_values[(lat_min<lat_values) & (lat_values<lat_max)]
- lon_lines, lat_lines = grid_finder._get_raw_grid_lines(lon_values0,
- lat_values0,
- lon_min, lon_max,
- lat_min, lat_max)
-
-
- grid_info["lon_lines"] = lon_lines
- grid_info["lat_lines"] = lat_lines
-
-
- lon_lines, lat_lines = grid_finder._get_raw_grid_lines(extremes[:2],
- extremes[2:],
- *extremes)
- #lon_min, lon_max,
- # lat_min, lat_max)
-
-
- grid_info["lon_lines0"] = lon_lines
- grid_info["lat_lines0"] = lat_lines
-
-
-
- def get_gridlines(self, which="major", axis="both"):
- grid_lines = []
- if axis in ["both", "x"]:
- for gl in self.grid_info["lon_lines"]:
- grid_lines.extend([gl])
- if axis in ["both", "y"]:
- for gl in self.grid_info["lat_lines"]:
- grid_lines.extend([gl])
-
- return grid_lines
-
-
- def get_boundary(self):
- """
- return Nx2 array of x,y coordinate of the boundary
- """
- x0, x1, y0, y1 = self._extremes
- tr = self._aux_trans
- xx = np.linspace(x0, x1, 100)
- yy0, yy1 = np.empty_like(xx), np.empty_like(xx)
- yy0.fill(y0)
- yy1.fill(y1)
-
- yy = np.linspace(y0, y1, 100)
- xx0, xx1 = np.empty_like(yy), np.empty_like(yy)
- xx0.fill(x0)
- xx1.fill(x1)
-
- xxx = np.concatenate([xx[:-1], xx1[:-1], xx[-1:0:-1], xx0])
- yyy = np.concatenate([yy0[:-1], yy[:-1], yy1[:-1], yy[::-1]])
- t = tr.transform(np.array([xxx, yyy]).transpose())
-
- return t
-
-
-
-
-
-
-
-
-
-
-
-
-class FloatingAxesBase(object):
-
-
- def __init__(self, *kl, **kwargs):
- grid_helper = kwargs.get("grid_helper", None)
- if grid_helper is None:
- raise ValueError("FloatingAxes requires grid_helper argument")
- if not hasattr(grid_helper, "get_boundary"):
- raise ValueError("grid_helper must implement get_boundary method")
-
- self._axes_class_floating.__init__(self, *kl, **kwargs)
-
- self.set_aspect(1.)
- self.adjust_axes_lim()
-
-
- def _gen_axes_patch(self):
- """
- Returns the patch used to draw the background of the axes. It
- is also used as the clipping path for any data elements on the
- axes.
-
- In the standard axes, this is a rectangle, but in other
- projections it may not be.
-
- .. note::
- Intended to be overridden by new projection types.
- """
- import matplotlib.patches as mpatches
- grid_helper = self.get_grid_helper()
- t = grid_helper.get_boundary()
- return mpatches.Polygon(t)
-
- def cla(self):
- self._axes_class_floating.cla(self)
- #HostAxes.cla(self)
- self.patch.set_transform(self.transData)
-
-
- patch = self._axes_class_floating._gen_axes_patch(self)
- patch.set_figure(self.figure)
- patch.set_visible(False)
- patch.set_transform(self.transAxes)
-
- self.patch.set_clip_path(patch)
- self.gridlines.set_clip_path(patch)
-
- self._original_patch = patch
-
-
- def adjust_axes_lim(self):
-
- #t = self.get_boundary()
- grid_helper = self.get_grid_helper()
- t = grid_helper.get_boundary()
- x, y = t[:,0], t[:,1]
-
- xmin, xmax = min(x), max(x)
- ymin, ymax = min(y), max(y)
-
- dx = (xmax-xmin)/100.
- dy = (ymax-ymin)/100.
-
- self.set_xlim(xmin-dx, xmax+dx)
- self.set_ylim(ymin-dy, ymax+dy)
-
-
-
-_floatingaxes_classes = {}
-
-def floatingaxes_class_factory(axes_class):
-
- new_class = _floatingaxes_classes.get(axes_class)
- if new_class is None:
- new_class = type(str("Floating %s" % (axes_class.__name__)),
- (FloatingAxesBase, axes_class),
- {'_axes_class_floating': axes_class})
- _floatingaxes_classes[axes_class] = new_class
-
- return new_class
-
-from .axislines import Axes
-from mpl_toolkits.axes_grid1.parasite_axes import host_axes_class_factory
-
-FloatingAxes = floatingaxes_class_factory(host_axes_class_factory(Axes))
-
-
-import matplotlib.axes as maxes
-FloatingSubplot = maxes.subplot_class_factory(FloatingAxes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py
deleted file mode 100644
index 62a94b14783..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py
+++ /dev/null
@@ -1,340 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from matplotlib.transforms import Bbox
-from . import clip_path
-clip_line_to_rect = clip_path.clip_line_to_rect
-
-import matplotlib.ticker as mticker
-from matplotlib.transforms import Transform
-
-# extremes finder
-
-class ExtremeFinderSimple(object):
- def __init__(self, nx, ny):
- self.nx, self.ny = nx, ny
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- get extreme values.
-
- x1, y1, x2, y2 in image coordinates (0-based)
- nx, ny : number of division in each axis
- """
- x_, y_ = np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)
- x, y = np.meshgrid(x_, y_)
- lon, lat = transform_xy(np.ravel(x), np.ravel(y))
-
- lon_min, lon_max = lon.min(), lon.max()
- lat_min, lat_max = lat.min(), lat.max()
-
- return self._add_pad(lon_min, lon_max, lat_min, lat_max)
-
- def _add_pad(self, lon_min, lon_max, lat_min, lat_max):
- """ a small amount of padding is added because the current
- clipping algorithms seems to fail when the gridline ends at
- the bbox boundary.
- """
- dlon = (lon_max - lon_min) / self.nx
- dlat = (lat_max - lat_min) / self.ny
-
- lon_min, lon_max = lon_min - dlon, lon_max + dlon
- lat_min, lat_max = lat_min - dlat, lat_max + dlat
-
- return lon_min, lon_max, lat_min, lat_max
-
-
-
-class GridFinderBase(object):
- def __init__(self,
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- the transData of the axes to the world coordinate.
- locator1, locator2 : grid locator for 1st and 2nd axis.
-
- Derived must define "transform_xy, inv_transform_xy"
- (may use update_transform)
- """
- super(GridFinderBase, self).__init__()
-
- self.extreme_finder = extreme_finder
- self.grid_locator1 = grid_locator1
- self.grid_locator2 = grid_locator2
- self.tick_formatter1 = tick_formatter1
- self.tick_formatter2 = tick_formatter2
-
- def get_grid_info(self,
- x1, y1, x2, y2):
- """
- lon_values, lat_values : list of grid values. if integer is given,
- rough number of grids in each direction.
- """
-
- extremes = self.extreme_finder(self.inv_transform_xy, x1, y1, x2, y2)
-
- # min & max rage of lat (or lon) for each grid line will be drawn.
- # i.e., gridline of lon=0 will be drawn from lat_min to lat_max.
-
- lon_min, lon_max, lat_min, lat_max = extremes
- lon_levs, lon_n, lon_factor = \
- self.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- self.grid_locator2(lat_min, lat_max)
-
- if lon_factor is None:
- lon_values = np.asarray(lon_levs[:lon_n])
- else:
- lon_values = np.asarray(lon_levs[:lon_n]/lon_factor)
- if lat_factor is None:
- lat_values = np.asarray(lat_levs[:lat_n])
- else:
- lat_values = np.asarray(lat_levs[:lat_n]/lat_factor)
-
-
- lon_lines, lat_lines = self._get_raw_grid_lines(lon_values,
- lat_values,
- lon_min, lon_max,
- lat_min, lat_max)
-
- ddx = (x2-x1)*1.e-10
- ddy = (y2-y1)*1.e-10
- bb = Bbox.from_extents(x1-ddx, y1-ddy, x2+ddx, y2+ddy)
-
- grid_info = {}
- grid_info["extremes"] = extremes
- grid_info["lon_lines"] = lon_lines
- grid_info["lat_lines"] = lat_lines
-
- grid_info["lon"] = self._clip_grid_lines_and_find_ticks(lon_lines,
- lon_values,
- lon_levs,
- bb)
-
- grid_info["lat"] = self._clip_grid_lines_and_find_ticks(lat_lines,
- lat_values,
- lat_levs,
- bb)
-
- tck_labels = grid_info["lon"]["tick_labels"] = dict()
- for direction in ["left", "bottom", "right", "top"]:
- levs = grid_info["lon"]["tick_levels"][direction]
- tck_labels[direction] = self.tick_formatter1(direction,
- lon_factor, levs)
-
- tck_labels = grid_info["lat"]["tick_labels"] = dict()
- for direction in ["left", "bottom", "right", "top"]:
- levs = grid_info["lat"]["tick_levels"][direction]
- tck_labels[direction] = self.tick_formatter2(direction,
- lat_factor, levs)
-
- return grid_info
-
-
- def _get_raw_grid_lines(self,
- lon_values, lat_values,
- lon_min, lon_max, lat_min, lat_max):
-
- lons_i = np.linspace(lon_min, lon_max, 100) # for interpolation
- lats_i = np.linspace(lat_min, lat_max, 100)
-
- lon_lines = [self.transform_xy(np.zeros_like(lats_i) + lon, lats_i)
- for lon in lon_values]
- lat_lines = [self.transform_xy(lons_i, np.zeros_like(lons_i) + lat)
- for lat in lat_values]
-
- return lon_lines, lat_lines
-
-
- def _clip_grid_lines_and_find_ticks(self, lines, values, levs, bb):
- gi = dict()
- gi["values"] = []
- gi["levels"] = []
- gi["tick_levels"] = dict(left=[], bottom=[], right=[], top=[])
- gi["tick_locs"] = dict(left=[], bottom=[], right=[], top=[])
- gi["lines"] = []
-
- tck_levels = gi["tick_levels"]
- tck_locs = gi["tick_locs"]
- for (lx, ly), v, lev in zip(lines, values, levs):
- xy, tcks = clip_line_to_rect(lx, ly, bb)
- if not xy:
- continue
- gi["levels"].append(v)
- gi["lines"].append(xy)
-
- for tck, direction in zip(tcks,
- ["left", "bottom", "right", "top"]):
- for t in tck:
- tck_levels[direction].append(lev)
- tck_locs[direction].append(t)
-
- return gi
-
-
- def update_transform(self, aux_trans):
- if isinstance(aux_trans, Transform):
- def transform_xy(x, y):
- x, y = np.asarray(x), np.asarray(y)
- ll1 = np.concatenate((x[:,np.newaxis], y[:,np.newaxis]), 1)
- ll2 = aux_trans.transform(ll1)
- lon, lat = ll2[:,0], ll2[:,1]
- return lon, lat
-
- def inv_transform_xy(x, y):
- x, y = np.asarray(x), np.asarray(y)
- ll1 = np.concatenate((x[:,np.newaxis], y[:,np.newaxis]), 1)
- ll2 = aux_trans.inverted().transform(ll1)
- lon, lat = ll2[:,0], ll2[:,1]
- return lon, lat
-
- else:
- transform_xy, inv_transform_xy = aux_trans
-
- self.transform_xy = transform_xy
- self.inv_transform_xy = inv_transform_xy
-
-
- def update(self, **kw):
- for k in kw:
- if k in ["extreme_finder",
- "grid_locator1",
- "grid_locator2",
- "tick_formatter1",
- "tick_formatter2"]:
- setattr(self, k, kw[k])
- else:
- raise ValueError("unknown update property '%s'" % k)
-
-
-class GridFinder(GridFinderBase):
-
- def __init__(self,
- transform,
- extreme_finder=None,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- transform : transform from the image coordinate (which will be
- the transData of the axes to the world coordinate.
-
- or transform = (transform_xy, inv_transform_xy)
-
- locator1, locator2 : grid locator for 1st and 2nd axis.
- """
- if extreme_finder is None:
- extreme_finder = ExtremeFinderSimple(20, 20)
- if grid_locator1 is None:
- grid_locator1 = MaxNLocator()
- if grid_locator2 is None:
- grid_locator2 = MaxNLocator()
- if tick_formatter1 is None:
- tick_formatter1 = FormatterPrettyPrint()
- if tick_formatter2 is None:
- tick_formatter2 = FormatterPrettyPrint()
- super(GridFinder, self).__init__(
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1,
- tick_formatter2)
- self.update_transform(transform)
-
-
-class MaxNLocator(mticker.MaxNLocator):
- def __init__(self, nbins=10, steps=None,
- trim=True,
- integer=False,
- symmetric=False,
- prune=None):
- # trim argument has no effect. It has been left for API compatibility
- mticker.MaxNLocator.__init__(self, nbins, steps=steps,
- integer=integer,
- symmetric=symmetric, prune=prune)
- self.create_dummy_axis()
- self._factor = None
-
- def __call__(self, v1, v2):
- if self._factor is not None:
- self.set_bounds(v1*self._factor, v2*self._factor)
- locs = mticker.MaxNLocator.__call__(self)
- return np.array(locs), len(locs), self._factor
- else:
- self.set_bounds(v1, v2)
- locs = mticker.MaxNLocator.__call__(self)
- return np.array(locs), len(locs), None
-
- def set_factor(self, f):
- self._factor = f
-
-
-class FixedLocator(object):
- def __init__(self, locs):
- self._locs = locs
- self._factor = None
-
-
- def __call__(self, v1, v2):
- if self._factor is None:
- v1, v2 = sorted([v1, v2])
- else:
- v1, v2 = sorted([v1*self._factor, v2*self._factor])
- locs = np.array([l for l in self._locs if ((v1 <= l) and (l <= v2))])
- return locs, len(locs), self._factor
-
- def set_factor(self, f):
- self._factor = f
-
-
-
-# Tick Formatter
-
-class FormatterPrettyPrint(object):
- def __init__(self, useMathText=True):
- self._fmt = mticker.ScalarFormatter(
- useMathText=useMathText, useOffset=False)
- self._fmt.create_dummy_axis()
- self._ignore_factor = True
-
- def __call__(self, direction, factor, values):
- if not self._ignore_factor:
- if factor is None:
- factor = 1.
- values = [v/factor for v in values]
- #values = [v for v in values]
- self._fmt.set_locs(values)
- return [self._fmt(v) for v in values]
-
-
-class DictFormatter(object):
- def __init__(self, format_dict, formatter=None):
- """
- format_dict : dictionary for format strings to be used.
- formatter : fall-back formatter
- """
- super(DictFormatter, self).__init__()
- self._format_dict = format_dict
- self._fallback_formatter = formatter
-
- def __call__(self, direction, factor, values):
- """
- factor is ignored if value is found in the dictionary
- """
-
- if self._fallback_formatter:
- fallback_strings = self._fallback_formatter(
- direction, factor, values)
- else:
- fallback_strings = [""]*len(values)
-
- r = [self._format_dict.get(k, v) for k, v in zip(values,
- fallback_strings)]
- return r
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py
deleted file mode 100644
index 578645148ee..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py
+++ /dev/null
@@ -1,475 +0,0 @@
-"""
-An experimental support for curvilinear grid.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-from itertools import chain
-from .grid_finder import GridFinder
-
-from .axislines import AxisArtistHelper, GridHelperBase
-from .axis_artist import AxisArtist
-from matplotlib.transforms import Affine2D, IdentityTransform
-import numpy as np
-
-from matplotlib.path import Path
-
-class FixedAxisArtistHelper(AxisArtistHelper.Fixed):
- """
- Helper class for a fixed axis.
- """
-
- def __init__(self, grid_helper, side, nth_coord_ticks=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- super(FixedAxisArtistHelper, self).__init__(loc=side)
-
- self.grid_helper = grid_helper
- if nth_coord_ticks is None:
- nth_coord_ticks = self.nth_coord
- self.nth_coord_ticks = nth_coord_ticks
-
- self.side = side
- self._limits_inverted = False
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- if self.nth_coord == 0:
- xy1, xy2 = axes.get_ylim()
- else:
- xy1, xy2 = axes.get_xlim()
-
- if xy1 > xy2:
- self._limits_inverted = True
- else:
- self._limits_inverted = False
-
-
- def change_tick_coord(self, coord_number=None):
- if coord_number is None:
- self.nth_coord_ticks = 1 - self.nth_coord_ticks
- elif coord_number in [0, 1]:
- self.nth_coord_ticks = coord_number
- else:
- raise Exception("wrong coord number")
-
-
- def get_tick_transform(self, axes):
- return axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
-
- g = self.grid_helper
-
- if self._limits_inverted:
- side = {"left":"right","right":"left",
- "top":"bottom", "bottom":"top"}[self.side]
- else:
- side = self.side
-
- ti1 = g.get_tick_iterator(self.nth_coord_ticks, side)
- ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, side, minor=True)
-
- #ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, self.side, minor=True)
-
- return chain(ti1, ti2), iter([])
-
-
-
-class FloatingAxisArtistHelper(AxisArtistHelper.Floating):
-
- def __init__(self, grid_helper, nth_coord, value, axis_direction=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- super(FloatingAxisArtistHelper, self).__init__(nth_coord,
- value,
- )
- self.value = value
- self.grid_helper = grid_helper
- self._extremes = None, None
-
- self._get_line_path = None # a method that returns a Path.
- self._line_num_points = 100 # number of points to create a line
-
- def set_extremes(self, e1, e2):
- self._extremes = e1, e2
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- x1, x2 = axes.get_xlim()
- y1, y2 = axes.get_ylim()
- grid_finder = self.grid_helper.grid_finder
- extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy,
- x1, y1, x2, y2)
-
- extremes = list(extremes)
- e1, e2 = self._extremes # ranges of other coordinates
- if self.nth_coord == 0:
- if e1 is not None:
- extremes[2] = max(e1, extremes[2])
- if e2 is not None:
- extremes[3] = min(e2, extremes[3])
- elif self.nth_coord == 1:
- if e1 is not None:
- extremes[0] = max(e1, extremes[0])
- if e2 is not None:
- extremes[1] = min(e2, extremes[1])
-
- grid_info = dict()
- lon_min, lon_max, lat_min, lat_max = extremes
- lon_levs, lon_n, lon_factor = \
- grid_finder.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- grid_finder.grid_locator2(lat_min, lat_max)
- grid_info["extremes"] = extremes
-
- grid_info["lon_info"] = lon_levs, lon_n, lon_factor
- grid_info["lat_info"] = lat_levs, lat_n, lat_factor
-
- grid_info["lon_labels"] = grid_finder.tick_formatter1("bottom",
- lon_factor,
- lon_levs)
-
- grid_info["lat_labels"] = grid_finder.tick_formatter2("bottom",
- lat_factor,
- lat_levs)
-
- grid_finder = self.grid_helper.grid_finder
-
- #e1, e2 = self._extremes # ranges of other coordinates
- if self.nth_coord == 0:
- xx0 = np.linspace(self.value, self.value, self._line_num_points)
- yy0 = np.linspace(extremes[2], extremes[3], self._line_num_points)
- xx, yy = grid_finder.transform_xy(xx0, yy0)
- elif self.nth_coord == 1:
- xx0 = np.linspace(extremes[0], extremes[1], self._line_num_points)
- yy0 = np.linspace(self.value, self.value, self._line_num_points)
- xx, yy = grid_finder.transform_xy(xx0, yy0)
-
- grid_info["line_xy"] = xx, yy
- self.grid_info = grid_info
-
- def get_axislabel_transform(self, axes):
- return Affine2D() #axes.transData
-
- def get_axislabel_pos_angle(self, axes):
-
- extremes = self.grid_info["extremes"]
-
- if self.nth_coord == 0:
- xx0 = self.value
- yy0 = (extremes[2]+extremes[3])/2.
- dxx, dyy = 0., abs(extremes[2]-extremes[3])/1000.
- elif self.nth_coord == 1:
- xx0 = (extremes[0]+extremes[1])/2.
- yy0 = self.value
- dxx, dyy = abs(extremes[0]-extremes[1])/1000., 0.
-
- grid_finder = self.grid_helper.grid_finder
- xx1, yy1 = grid_finder.transform_xy([xx0], [yy0])
-
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([xx1[0], yy1[0]])
-
-
- if (0. <= p[0] <= 1.) and (0. <= p[1] <= 1.):
- xx1c, yy1c = axes.transData.transform_point([xx1[0], yy1[0]])
- xx2, yy2 = grid_finder.transform_xy([xx0+dxx], [yy0+dyy])
- xx2c, yy2c = axes.transData.transform_point([xx2[0], yy2[0]])
-
- return (xx1c, yy1c), np.arctan2(yy2c-yy1c, xx2c-xx1c)/np.pi*180.
- else:
- return None, None
-
-
-
-
- def get_tick_transform(self, axes):
- return IdentityTransform() #axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label, (optionally) tick_label"""
-
- grid_finder = self.grid_helper.grid_finder
-
- lat_levs, lat_n, lat_factor = self.grid_info["lat_info"]
- lat_levs = np.asarray(lat_levs)
- if lat_factor is not None:
- yy0 = lat_levs / lat_factor
- dy = 0.01 / lat_factor
- else:
- yy0 = lat_levs
- dy = 0.01
-
- lon_levs, lon_n, lon_factor = self.grid_info["lon_info"]
- lon_levs = np.asarray(lon_levs)
- if lon_factor is not None:
- xx0 = lon_levs / lon_factor
- dx = 0.01 / lon_factor
- else:
- xx0 = lon_levs
- dx = 0.01
-
- if None in self._extremes:
- e0, e1 = self._extremes
- else:
- e0, e1 = sorted(self._extremes)
- if e0 is None:
- e0 = -np.inf
- if e1 is None:
- e1 = np.inf
-
- if self.nth_coord == 0:
- mask = (e0 <= yy0) & (yy0 <= e1)
- #xx0, yy0 = xx0[mask], yy0[mask]
- yy0 = yy0[mask]
- elif self.nth_coord == 1:
- mask = (e0 <= xx0) & (xx0 <= e1)
- #xx0, yy0 = xx0[mask], yy0[mask]
- xx0 = xx0[mask]
-
- def transform_xy(x, y):
- x1, y1 = grid_finder.transform_xy(x, y)
- x2y2 = axes.transData.transform(np.array([x1, y1]).transpose())
- x2, y2 = x2y2.transpose()
- return x2, y2
-
- # find angles
- if self.nth_coord == 0:
- xx0 = np.empty_like(yy0)
- xx0.fill(self.value)
-
- xx1, yy1 = transform_xy(xx0, yy0)
-
- xx00 = xx0.copy()
- xx00[xx0+dx>e1] -= dx
- xx1a, yy1a = transform_xy(xx00, yy0)
- xx1b, yy1b = transform_xy(xx00+dx, yy0)
-
- xx2a, yy2a = transform_xy(xx0, yy0)
- xx2b, yy2b = transform_xy(xx0, yy0+dy)
-
- labels = self.grid_info["lat_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
- elif self.nth_coord == 1:
- yy0 = np.empty_like(xx0)
- yy0.fill(self.value)
-
- xx1, yy1 = transform_xy(xx0, yy0)
-
- xx1a, yy1a = transform_xy(xx0, yy0)
- xx1b, yy1b = transform_xy(xx0, yy0+dy)
-
- xx00 = xx0.copy()
- xx00[xx0+dx>e1] -= dx
- xx2a, yy2a = transform_xy(xx00, yy0)
- xx2b, yy2b = transform_xy(xx00+dx, yy0)
-
- labels = self.grid_info["lon_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
-
- def f1():
- dd = np.arctan2(yy1b-yy1a, xx1b-xx1a) # angle normal
- dd2 = np.arctan2(yy2b-yy2a, xx2b-xx2a) # angle tangent
- mm = ((yy1b-yy1a)==0.) & ((xx1b-xx1a)==0.) # mask where dd1 is not defined
- dd[mm] = dd2[mm] + np.pi / 2
- #dd = np.arctan2(yy2-yy1, xx2-xx1) # angle normal
- #dd2 = np.arctan2(yy3-yy1, xx3-xx1) # angle tangent
- #mm = ((yy2-yy1)==0.) & ((xx2-xx1)==0.) # mask where dd1 is not defined
- #dd[mm] = dd2[mm] + np.pi / 2
-
- #dd += np.pi
-
- #dd = np.arctan2(xx2-xx1, angle_tangent-yy1)
- trans_tick = self.get_tick_transform(axes)
- tr2ax = trans_tick + axes.transAxes.inverted()
- for x, y, d, d2, lab in zip(xx1, yy1, dd, dd2, labels):
- c2 = tr2ax.transform_point((x, y))
- delta=0.00001
- if (0. -delta<= c2[0] <= 1.+delta) and \
- (0. -delta<= c2[1] <= 1.+delta):
- d1 = d/3.14159*180.
- d2 = d2/3.14159*180.
- yield [x, y], d1, d2, lab
-
- return f1(), iter([])
-
- def get_line_transform(self, axes):
- return axes.transData
-
- def get_line(self, axes):
- self.update_lim(axes)
- x, y = self.grid_info["line_xy"]
-
- if self._get_line_path is None:
- return Path(np.column_stack([x, y]))
- else:
- return self._get_line_path(axes, x, y)
-
-
-
-
-class GridHelperCurveLinear(GridHelperBase):
-
- def __init__(self, aux_trans,
- extreme_finder=None,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- aux_trans : a transform from the source (curved) coordinate to
- target (rectilinear) coordinate. An instance of MPL's Transform
- (inverse transform should be defined) or a tuple of two callable
- objects which defines the transform and its inverse. The callables
- need take two arguments of array of source coordinates and
- should return two target coordinates.
-
- e.g., ``x2, y2 = trans(x1, y1)``
- """
- super(GridHelperCurveLinear, self).__init__()
-
- self.grid_info = None
- self._old_values = None
- #self._grid_params = dict()
- self._aux_trans = aux_trans
-
- self.grid_finder = GridFinder(aux_trans,
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1,
- tick_formatter2)
-
-
- def update_grid_finder(self, aux_trans=None, **kw):
-
- if aux_trans is not None:
- self.grid_finder.update_transform(aux_trans)
-
- self.grid_finder.update(**kw)
- self.invalidate()
-
-
- def _update(self, x1, x2, y1, y2):
- "bbox in 0-based image coordinates"
- # update wcsgrid
-
- if self.valid() and self._old_values == (x1, x2, y1, y2):
- return
-
- self._update_grid(x1, y1, x2, y2)
-
- self._old_values = (x1, x2, y1, y2)
-
- self._force_update = False
-
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None):
-
-
- if axes is None:
- axes = self.axes
-
- if axis_direction is None:
- axis_direction = loc
- _helper = FixedAxisArtistHelper(self, loc,
- #nth_coord,
- nth_coord_ticks=nth_coord,
- )
-
- axisline = AxisArtist(axes, _helper, axis_direction=axis_direction)
-
- return axisline
-
-
- def new_floating_axis(self, nth_coord,
- value,
- axes=None,
- axis_direction="bottom"
- ):
-
- if axes is None:
- axes = self.axes
-
- _helper = FloatingAxisArtistHelper(
- self, nth_coord, value, axis_direction)
-
- axisline = AxisArtist(axes, _helper)
-
- #_helper = FloatingAxisArtistHelper(self, nth_coord,
- # value,
- # label_direction=label_direction,
- # )
-
- #axisline = AxisArtistFloating(axes, _helper,
- # axis_direction=axis_direction)
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- #axisline.major_ticklabels.set_visible(True)
- #axisline.minor_ticklabels.set_visible(False)
-
- #axisline.major_ticklabels.set_rotate_along_line(True)
- #axisline.set_rotate_label_along_line(True)
-
- return axisline
-
-
- def _update_grid(self, x1, y1, x2, y2):
-
- self.grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2)
-
-
- def get_gridlines(self, which="major", axis="both"):
- grid_lines = []
-
- if axis in ["both", "x"]:
- for gl in self.grid_info["lon"]["lines"]:
- grid_lines.extend(gl)
- if axis in ["both", "y"]:
- for gl in self.grid_info["lat"]["lines"]:
- grid_lines.extend(gl)
-
- return grid_lines
-
-
- def get_tick_iterator(self, nth_coord, axis_side, minor=False):
-
- #axisnr = dict(left=0, bottom=1, right=2, top=3)[axis_side]
- angle_tangent = dict(left=90, right=90, bottom=0, top=0)[axis_side]
- #angle = [0, 90, 180, 270][axisnr]
- lon_or_lat = ["lon", "lat"][nth_coord]
- if not minor: # major ticks
- def f():
- for (xy, a), l in zip(self.grid_info[lon_or_lat]["tick_locs"][axis_side],
- self.grid_info[lon_or_lat]["tick_labels"][axis_side]):
- angle_normal = a
- yield xy, angle_normal, angle_tangent, l
- else:
- def f():
- for (xy, a), l in zip(self.grid_info[lon_or_lat]["tick_locs"][axis_side],
- self.grid_info[lon_or_lat]["tick_labels"][axis_side]):
- angle_normal = a
- yield xy, angle_normal, angle_tangent, ""
- #for xy, a, l in self.grid_info[lon_or_lat]["ticks"][axis_side]:
- # yield xy, a, ""
-
- return f()
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py
deleted file mode 100644
index cad56e43a22..00000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory,
- parasite_axes_auxtrans_class_factory, subplot_class_factory)
-
-from .axislines import Axes
-
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-ParasiteAxesAuxTrans = \
- parasite_axes_auxtrans_class_factory(axes_class=ParasiteAxes)
-
-HostAxes = host_axes_class_factory(axes_class=Axes)
-
-SubplotHost = subplot_class_factory(HostAxes)