From a4f8b56908ce23a1ed45d82fc73a994ab81d8a1d Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 17 Aug 2016 12:28:34 +0100
Subject: [PATCH 01/11] Ensured xarray returns raw data in range
Fix for datetime64
---
holoviews/core/data/xarray.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/holoviews/core/data/xarray.py b/holoviews/core/data/xarray.py
index a293d4ecc3..4fe9ef3644 100644
--- a/holoviews/core/data/xarray.py
+++ b/holoviews/core/data/xarray.py
@@ -78,7 +78,7 @@ def range(cls, dataset, dimension):
dim = dataset.get_dimension(dimension).name
if dim in dataset.data:
data = dataset.data[dim]
- return data.min().item(), data.max().item()
+ return data.min().data, data.max().data
else:
return np.NaN, np.NaN
From f0e33d219b9b358d319f8c524a85d756f5371982 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 17 Aug 2016 12:29:50 +0100
Subject: [PATCH 02/11] Added handling of datetime64 to matplotlib range
handling
---
holoviews/plotting/mpl/element.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py
index a481e17dd3..f39aaa63e8 100644
--- a/holoviews/plotting/mpl/element.py
+++ b/holoviews/plotting/mpl/element.py
@@ -1,4 +1,5 @@
import math
+import datetime as dt
from matplotlib import ticker
from matplotlib import colors
@@ -302,6 +303,8 @@ def _set_axis_limits(self, axis, view, subplots, ranges):
extents = self.get_extents(view, ranges)
if extents and not self.overlaid:
coords = [coord if np.isreal(coord) else np.NaN for coord in extents]
+ coords = [c.astype(dt.datetime) if isinstance(c, np.datetime64) else c
+ for c in coords]
valid_lim = lambda c: util.isnumeric(c) and not np.isnan(c)
if self.projection == '3d' or len(extents) == 6:
l, b, zmin, r, t, zmax = coords
From a720c2a4c32fb50d14dcc253ffc9b7500cb49fac Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 17 Aug 2016 12:31:24 +0100
Subject: [PATCH 03/11] Safely handle datetime64 in matplotlib Curve plots
---
holoviews/plotting/mpl/chart.py | 12 +++++++++++-
holoviews/plotting/util.py | 9 +++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/holoviews/plotting/mpl/chart.py b/holoviews/plotting/mpl/chart.py
index 2a9846cab3..673667a182 100644
--- a/holoviews/plotting/mpl/chart.py
+++ b/holoviews/plotting/mpl/chart.py
@@ -1,10 +1,12 @@
from __future__ import unicode_literals
+
from itertools import product
import numpy as np
from matplotlib import cm
from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection
+from matplotlib.dates import date2num
import param
@@ -12,7 +14,7 @@
from ...core.util import (match_spec, unique_iterator, safe_unicode,
basestring, max_range, unicode)
from ...element import Points, Raster, Polygons, HeatMap
-from ..util import compute_sizes, get_sideplot_ranges
+from ..util import compute_sizes, get_sideplot_ranges, dt64_to_dt
from .element import ElementPlot, ColorbarPlot, LegendPlot
from .path import PathPlot
from .plot import AdjoinedPlot
@@ -61,6 +63,14 @@ def get_data(self, element, ranges, style):
ys = element.dimension_values(1)
return (xs, ys), style, {}
+ def init_artists(self, ax, plot_args, plot_kwargs):
+ xs, ys = plot_args
+ if xs.dtype.kind == 'M':
+ xs = np.array([date2num(dt64_to_dt(x)) for x in xs])
+ artist = ax.plot_date(xs, ys, '-', **plot_kwargs)[0]
+ else:
+ artist = ax.plot(xs, ys, **plot_kwargs)[0]
+ return {'artist': artist}
def update_handles(self, key, axis, element, ranges, style):
artist = self.handles['artist']
diff --git a/holoviews/plotting/util.py b/holoviews/plotting/util.py
index 727bdffdcd..f723d68514 100644
--- a/holoviews/plotting/util.py
+++ b/holoviews/plotting/util.py
@@ -1,5 +1,7 @@
from __future__ import unicode_literals
+from datetime import datetime as dt
+
import numpy as np
import param
@@ -270,3 +272,10 @@ def dim_axis_label(dimensions, separator=', '):
if not isinstance(dimensions, list): dimensions = [dimensions]
return separator.join([safe_unicode(d.pprint_label)
for d in dimensions])
+
+def dt64_to_dt(dt64):
+ """
+ Safely converts NumPy datetime64 to a datetime object.
+ """
+ ts = (dt64 - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's')
+ return dt.utcfromtimestamp(ts)
From eba660c8135b006dd4302fac083cabd966d715f1 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 17 Aug 2016 13:50:55 +0100
Subject: [PATCH 04/11] Further small fix for xarray datetime64 ranges
---
holoviews/core/data/xarray.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/holoviews/core/data/xarray.py b/holoviews/core/data/xarray.py
index 4fe9ef3644..16c15fd688 100644
--- a/holoviews/core/data/xarray.py
+++ b/holoviews/core/data/xarray.py
@@ -78,7 +78,10 @@ def range(cls, dataset, dimension):
dim = dataset.get_dimension(dimension).name
if dim in dataset.data:
data = dataset.data[dim]
- return data.min().data, data.max().data
+ dmin, dmax = data.min().data, data.max().data
+ dmin = dmin if np.isscalar(dmin) else dmin.item()
+ dmax = dmax if np.isscalar(dmax) else dmax.item()
+ return dmin, dmax
else:
return np.NaN, np.NaN
From ae6369bb5b540a85a6a1acda041c4910908cf69c Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 17 Aug 2016 13:51:26 +0100
Subject: [PATCH 05/11] Fix for Dateset datetime64 type lookup
---
holoviews/core/data/__init__.py | 2 +-
holoviews/core/data/grid.py | 6 ++----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/holoviews/core/data/__init__.py b/holoviews/core/data/__init__.py
index a159f297a1..f266adbe45 100644
--- a/holoviews/core/data/__init__.py
+++ b/holoviews/core/data/__init__.py
@@ -463,7 +463,7 @@ def get_dimension_type(self, dim):
dim_obj = self.get_dimension(dim)
if dim_obj and dim_obj.type is not None:
return dim_obj.type
- return self.interface.dimension_type(self, dim)
+ return self.interface.dimension_type(self, dim_obj)
def dframe(self, dimensions=None):
diff --git a/holoviews/core/data/grid.py b/holoviews/core/data/grid.py
index 36c533b1b7..e4df29006d 100644
--- a/holoviews/core/data/grid.py
+++ b/holoviews/core/data/grid.py
@@ -84,10 +84,8 @@ def validate(cls, dataset):
@classmethod
def dimension_type(cls, dataset, dim):
- if dim in dataset.kdims:
- arr = dataset.data[dim.name]
- elif dim in dataset.vdims:
- arr = dataset.data[dim.name]
+ if dim in dataset.dimensions():
+ arr = cls.values(dataset, dim, False, False)
else:
return None
return arr.dtype.type
From f801d42bc47b650f527b1f978bc42eec76c9ffd7 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 18 Aug 2016 10:55:01 +0100
Subject: [PATCH 06/11] Simplified datetime64 handling in matplotlib
---
holoviews/plotting/mpl/chart.py | 1 -
holoviews/plotting/mpl/element.py | 14 +++++++-------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/holoviews/plotting/mpl/chart.py b/holoviews/plotting/mpl/chart.py
index 673667a182..d2f2da7d01 100644
--- a/holoviews/plotting/mpl/chart.py
+++ b/holoviews/plotting/mpl/chart.py
@@ -66,7 +66,6 @@ def get_data(self, element, ranges, style):
def init_artists(self, ax, plot_args, plot_kwargs):
xs, ys = plot_args
if xs.dtype.kind == 'M':
- xs = np.array([date2num(dt64_to_dt(x)) for x in xs])
artist = ax.plot_date(xs, ys, '-', **plot_kwargs)[0]
else:
artist = ax.plot(xs, ys, **plot_kwargs)[0]
diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py
index f39aaa63e8..bd43651a6f 100644
--- a/holoviews/plotting/mpl/element.py
+++ b/holoviews/plotting/mpl/element.py
@@ -1,18 +1,18 @@
import math
-import datetime as dt
+import param
+import numpy as np
+import matplotlib.pyplot as plt
from matplotlib import ticker
from matplotlib import colors
-import matplotlib.pyplot as plt
-import numpy as np
-import param
+from matplotlib.dates import date2num
from ...core import util
from ...core import (OrderedDict, NdOverlay, DynamicMap,
CompositeOverlay, Element3D, Element)
from ...core.options import abbreviated_exception
from ..plot import GenericElementPlot, GenericOverlayPlot
-from ..util import dynamic_update
+from ..util import dynamic_update, dt64_to_dt
from .plot import MPLPlot
from .util import wrap_formatter
@@ -302,8 +302,8 @@ def _set_axis_limits(self, axis, view, subplots, ranges):
scalex, scaley = True, True
extents = self.get_extents(view, ranges)
if extents and not self.overlaid:
- coords = [coord if np.isreal(coord) else np.NaN for coord in extents]
- coords = [c.astype(dt.datetime) if isinstance(c, np.datetime64) else c
+ coords = [coord if np.isreal(coord) or isinstance(coord, np.datetime64) else np.NaN for coord in extents]
+ coords = [date2num(dt64_to_dt(c)) if isinstance(c, np.datetime64) else c
for c in coords]
valid_lim = lambda c: util.isnumeric(c) and not np.isnan(c)
if self.projection == '3d' or len(extents) == 6:
From 8d4392d7f8a9f8755c1684b381d337c8f21f4674 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 18 Aug 2016 10:55:53 +0100
Subject: [PATCH 07/11] Unified tick formatting on matplotlib Grid plots
---
holoviews/plotting/mpl/plot.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/holoviews/plotting/mpl/plot.py b/holoviews/plotting/mpl/plot.py
index faae2e9580..907fed2cdf 100644
--- a/holoviews/plotting/mpl/plot.py
+++ b/holoviews/plotting/mpl/plot.py
@@ -262,9 +262,6 @@ class GridPlot(CompositePlot):
show_legend = param.Boolean(default=False, doc="""
Legends add to much clutter in a grid and are disabled by default.""")
- tick_format = param.String(default="%.2f", doc="""
- Formatting string for the GridPlot ticklabels.""")
-
xaxis = param.ObjectSelector(default='bottom',
objects=['bottom', 'top', None], doc="""
Whether and where to display the xaxis, supported options are
@@ -534,10 +531,13 @@ def _process_ticklabels(self, labels, dim):
for k in labels:
if dim and dim.value_format:
k = dim.value_format(k)
- elif not isinstance(k, (str, type(None))):
- k = self.tick_format % k
+ elif dim.type in dim.type_formatters:
+ formatter = dim.type_formatters[dim.type]
+ k = formatter % k
elif k is None:
k = ''
+ else:
+ k = str(k)
formatted_labels.append(k)
return formatted_labels
From 354086808c0b4bde83159ab650e7ca77f7269ee4 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 18 Aug 2016 11:39:26 +0100
Subject: [PATCH 08/11] Allowed setting datetime formatters on dimensions
---
holoviews/core/__init__.py | 1 +
holoviews/core/dimension.py | 9 +++++++--
holoviews/core/util.py | 8 ++++++++
holoviews/plotting/mpl/chart.py | 12 ++++++++----
holoviews/plotting/mpl/element.py | 4 ++--
holoviews/plotting/util.py | 9 ---------
6 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/holoviews/core/__init__.py b/holoviews/core/__init__.py
index 2146af3e90..2a4dd7deb2 100644
--- a/holoviews/core/__init__.py
+++ b/holoviews/core/__init__.py
@@ -17,6 +17,7 @@
Dimension.type_formatters[float] = "%.5g"
Dimension.type_formatters[np.float32] = "%.5g"
Dimension.type_formatters[np.float64] = "%.5g"
+Dimension.type_formatters[np.datetime64] = '%Y-%m-%d %H:%M:%S'
def public(obj):
diff --git a/holoviews/core/dimension.py b/holoviews/core/dimension.py
index 8925e693f9..089a0475de 100644
--- a/holoviews/core/dimension.py
+++ b/holoviews/core/dimension.py
@@ -5,6 +5,7 @@
"""
from __future__ import unicode_literals
import re
+import datetime as dt
from operator import itemgetter
import numpy as np
@@ -13,7 +14,7 @@
from ..core.util import (basestring, sanitize_identifier,
group_sanitizer, label_sanitizer, max_range,
find_range, dimension_sanitizer, OrderedDict,
- safe_unicode, unicode)
+ safe_unicode, unicode, dt64_to_dt)
from .options import Store, StoreOptions
from .pprint import PrettyPrinter
@@ -178,7 +179,11 @@ def pprint_value(self, value):
if callable(formatter):
return formatter(value)
elif isinstance(formatter, basestring):
- if re.findall(r"\{(\w+)\}", formatter):
+ if isinstance(value, dt.datetime):
+ return value.strftime(formatter)
+ elif isinstance(value, np.datetime64):
+ return dt64_to_dt(value).strftime(formatter)
+ elif re.findall(r"\{(\w+)\}", formatter):
return formatter.format(value)
else:
return formatter % value
diff --git a/holoviews/core/util.py b/holoviews/core/util.py
index 7e558c268f..13c0d44324 100644
--- a/holoviews/core/util.py
+++ b/holoviews/core/util.py
@@ -3,6 +3,7 @@
import itertools
import string, fnmatch
import unicodedata
+import datetime as dt
from collections import defaultdict
import numpy as np
@@ -917,3 +918,10 @@ def expand_grid_coords(dataset, dim):
idx = dataset.get_dimension_index(dim)
return cartesian_product(arrays)[idx]
+
+def dt64_to_dt(dt64):
+ """
+ Safely converts NumPy datetime64 to a datetime object.
+ """
+ ts = (dt64 - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's')
+ return dt.datetime.utcfromtimestamp(ts)
diff --git a/holoviews/plotting/mpl/chart.py b/holoviews/plotting/mpl/chart.py
index d2f2da7d01..a2fd2120f1 100644
--- a/holoviews/plotting/mpl/chart.py
+++ b/holoviews/plotting/mpl/chart.py
@@ -6,15 +6,15 @@
from matplotlib import cm
from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection
-from matplotlib.dates import date2num
+from matplotlib.dates import date2num, DateFormatter
import param
-from ...core import OrderedDict
+from ...core import OrderedDict, Dimension
from ...core.util import (match_spec, unique_iterator, safe_unicode,
basestring, max_range, unicode)
from ...element import Points, Raster, Polygons, HeatMap
-from ..util import compute_sizes, get_sideplot_ranges, dt64_to_dt
+from ..util import compute_sizes, get_sideplot_ranges
from .element import ElementPlot, ColorbarPlot, LegendPlot
from .path import PathPlot
from .plot import AdjoinedPlot
@@ -61,7 +61,11 @@ class CurvePlot(ChartPlot):
def get_data(self, element, ranges, style):
xs = element.dimension_values(0)
ys = element.dimension_values(1)
- return (xs, ys), style, {}
+ dims = element.dimensions()
+ if xs.dtype.kind == 'M':
+ dt_format = Dimension.type_formatters[np.datetime64]
+ dims[0] = dims[0](value_format=DateFormatter(dt_format))
+ return (xs, ys), style, {'dimensions': dims}
def init_artists(self, ax, plot_args, plot_kwargs):
xs, ys = plot_args
diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py
index bd43651a6f..d899082463 100644
--- a/holoviews/plotting/mpl/element.py
+++ b/holoviews/plotting/mpl/element.py
@@ -12,7 +12,7 @@
CompositeOverlay, Element3D, Element)
from ...core.options import abbreviated_exception
from ..plot import GenericElementPlot, GenericOverlayPlot
-from ..util import dynamic_update, dt64_to_dt
+from ..util import dynamic_update
from .plot import MPLPlot
from .util import wrap_formatter
@@ -303,7 +303,7 @@ def _set_axis_limits(self, axis, view, subplots, ranges):
extents = self.get_extents(view, ranges)
if extents and not self.overlaid:
coords = [coord if np.isreal(coord) or isinstance(coord, np.datetime64) else np.NaN for coord in extents]
- coords = [date2num(dt64_to_dt(c)) if isinstance(c, np.datetime64) else c
+ coords = [date2num(util.dt64_to_dt(c)) if isinstance(c, np.datetime64) else c
for c in coords]
valid_lim = lambda c: util.isnumeric(c) and not np.isnan(c)
if self.projection == '3d' or len(extents) == 6:
diff --git a/holoviews/plotting/util.py b/holoviews/plotting/util.py
index f723d68514..727bdffdcd 100644
--- a/holoviews/plotting/util.py
+++ b/holoviews/plotting/util.py
@@ -1,7 +1,5 @@
from __future__ import unicode_literals
-from datetime import datetime as dt
-
import numpy as np
import param
@@ -272,10 +270,3 @@ def dim_axis_label(dimensions, separator=', '):
if not isinstance(dimensions, list): dimensions = [dimensions]
return separator.join([safe_unicode(d.pprint_label)
for d in dimensions])
-
-def dt64_to_dt(dt64):
- """
- Safely converts NumPy datetime64 to a datetime object.
- """
- ts = (dt64 - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's')
- return dt.utcfromtimestamp(ts)
From 97763aff8170539f8a6b2247ec6b277776779735 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 18 Aug 2016 11:48:26 +0100
Subject: [PATCH 09/11] Cleaned up mpl GridPlot tick formatting
---
holoviews/plotting/mpl/plot.py | 22 ++++------------------
1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/holoviews/plotting/mpl/plot.py b/holoviews/plotting/mpl/plot.py
index 907fed2cdf..87c34f9df9 100644
--- a/holoviews/plotting/mpl/plot.py
+++ b/holoviews/plotting/mpl/plot.py
@@ -493,13 +493,15 @@ def _layout_axis(self, layout, axis):
yticks = [(plot_height/2)+(r*(plot_height+border_height)) for r in range(self.rows)]
layout_axis.set_xticks(xticks)
- layout_axis.set_xticklabels(self._process_ticklabels(sorted(set(dim1_keys)), dims[0]))
+ layout_axis.set_xticklabels([dims[0].pprint_value(l)
+ for l in sorted(set(dim1_keys))])
for tick in layout_axis.get_xticklabels():
tick.set_rotation(self.xrotation)
ydim = dims[1] if layout.ndims > 1 else None
layout_axis.set_yticks(yticks)
- layout_axis.set_yticklabels(self._process_ticklabels(sorted(set(dim2_keys)), ydim))
+ layout_axis.set_yticklabels([ydim.pprint_value(l) if ydim else l
+ for l in sorted(set(dim2_keys))])
for tick in layout_axis.get_yticklabels():
tick.set_rotation(self.yrotation)
@@ -526,22 +528,6 @@ def _layout_axis(self, layout, axis):
return layout_axis
- def _process_ticklabels(self, labels, dim):
- formatted_labels = []
- for k in labels:
- if dim and dim.value_format:
- k = dim.value_format(k)
- elif dim.type in dim.type_formatters:
- formatter = dim.type_formatters[dim.type]
- k = formatter % k
- elif k is None:
- k = ''
- else:
- k = str(k)
- formatted_labels.append(k)
- return formatted_labels
-
-
def _adjust_subplots(self, axis, subaxes):
bbox = axis.get_position()
l, b, w, h = bbox.x0, bbox.y0, bbox.width, bbox.height
From 4d6714f27b118cba3a0a864bd601d636f5286325 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 18 Aug 2016 13:14:59 +0100
Subject: [PATCH 10/11] Fixed RasterGridPlot tick formatting
---
holoviews/plotting/mpl/raster.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/holoviews/plotting/mpl/raster.py b/holoviews/plotting/mpl/raster.py
index a734fecf39..4eaec6a75c 100644
--- a/holoviews/plotting/mpl/raster.py
+++ b/holoviews/plotting/mpl/raster.py
@@ -379,8 +379,9 @@ def update_frame(self, key, ranges=None):
def _get_axis_kwargs(self):
xdim = self.layout.kdims[0]
ydim = self.layout.kdims[1] if self.layout.ndims > 1 else None
- xticks = (self._xticks, self._process_ticklabels(self._xkeys, xdim))
- yticks = (self._yticks, self._process_ticklabels(self._ykeys, ydim))
+ xticks = (self._xticks, [xdim.pprint_value(l) for l in self._xkeys])
+ yticks = (self._yticks, [ydim.pprint_value(l) if ydim else l
+ for l in self._ykeys])
return dict(xlabel=xdim.pprint_label, ylabel=ydim.pprint_label if ydim else '',
xticks=xticks, yticks=yticks)
From 09bf924324ff319ac2b9adcd36194cd8771e83a8 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Thu, 18 Aug 2016 14:14:31 +0100
Subject: [PATCH 11/11] Small fix for 1D grid tick formatting
---
holoviews/plotting/mpl/plot.py | 2 +-
holoviews/plotting/mpl/raster.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/holoviews/plotting/mpl/plot.py b/holoviews/plotting/mpl/plot.py
index 87c34f9df9..2d24f82ea5 100644
--- a/holoviews/plotting/mpl/plot.py
+++ b/holoviews/plotting/mpl/plot.py
@@ -500,7 +500,7 @@ def _layout_axis(self, layout, axis):
ydim = dims[1] if layout.ndims > 1 else None
layout_axis.set_yticks(yticks)
- layout_axis.set_yticklabels([ydim.pprint_value(l) if ydim else l
+ layout_axis.set_yticklabels([ydim.pprint_value(l) if ydim else ''
for l in sorted(set(dim2_keys))])
for tick in layout_axis.get_yticklabels():
tick.set_rotation(self.yrotation)
diff --git a/holoviews/plotting/mpl/raster.py b/holoviews/plotting/mpl/raster.py
index 4eaec6a75c..9f70fcd2bf 100644
--- a/holoviews/plotting/mpl/raster.py
+++ b/holoviews/plotting/mpl/raster.py
@@ -380,7 +380,7 @@ def _get_axis_kwargs(self):
xdim = self.layout.kdims[0]
ydim = self.layout.kdims[1] if self.layout.ndims > 1 else None
xticks = (self._xticks, [xdim.pprint_value(l) for l in self._xkeys])
- yticks = (self._yticks, [ydim.pprint_value(l) if ydim else l
+ yticks = (self._yticks, [ydim.pprint_value(l) if ydim else ''
for l in self._ykeys])
return dict(xlabel=xdim.pprint_label, ylabel=ydim.pprint_label if ydim else '',
xticks=xticks, yticks=yticks)