diff options
author | maxim-yurchuk <maxim-yurchuk@yandex-team.com> | 2025-02-11 13:26:52 +0300 |
---|---|---|
committer | maxim-yurchuk <maxim-yurchuk@yandex-team.com> | 2025-02-11 13:57:59 +0300 |
commit | f895bba65827952ed934b2b46f9a45e30a191fd2 (patch) | |
tree | 03260c906d9ec41cdc03e2a496b15d407459cec0 /contrib/python/matplotlib/py2/mpl_toolkits/axisartist | |
parent | 5f7060466f7b9707818c2091e1a25c14f33c3474 (diff) | |
download | ydb-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')
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) |