diff options
Diffstat (limited to 'silx/gui/plot/backends')
-rw-r--r-- | silx/gui/plot/backends/BackendBase.py | 17 | ||||
-rw-r--r-- | silx/gui/plot/backends/BackendMatplotlib.py | 28 | ||||
-rw-r--r-- | silx/gui/plot/backends/BackendOpenGL.py | 17 | ||||
-rw-r--r-- | silx/gui/plot/backends/glutils/GLText.py | 46 |
4 files changed, 85 insertions, 23 deletions
diff --git a/silx/gui/plot/backends/BackendBase.py b/silx/gui/plot/backends/BackendBase.py index 8352ea0..7fb8be0 100644 --- a/silx/gui/plot/backends/BackendBase.py +++ b/silx/gui/plot/backends/BackendBase.py @@ -163,9 +163,8 @@ class BackendBase(object): :param int z: Layer on which to draw the image :param bool selectable: indicate if the image can be selected :param bool draggable: indicate if the image can be moved - :param colormap: :class:`.Colormap` describing the colormap to use. - Ignored if data is RGB(A). - :type colormap: :class:`.Colormap` + :param ~silx.gui.colors.Colormap colormap: Colormap object to use. + Ignored if data is RGB(A). :param float alpha: Opacity of the image, as a float in range [0, 1]. :returns: The handle used by the backend to univocally access the image """ @@ -189,7 +188,7 @@ class BackendBase(object): def addMarker(self, x, y, legend, text, color, selectable, draggable, - symbol, constraint): + symbol, linestyle, linewidth, constraint): """Add a point, vertical line or horizontal line marker to the plot. :param float x: Horizontal position of the marker in graph coordinates. @@ -212,7 +211,17 @@ class BackendBase(object): - 'x' x-cross - 'd' diamond - 's' square + :param str linestyle: Style of the line. + Only relevant for line markers where X or Y is None. + Value in: + - ' ' no line + - '-' solid line + - '--' dashed line + - '-.' dash-dot line + - ':' dotted line + :param float linewidth: Width of the line. + Only relevant for line markers where X or Y is None. :param constraint: A function filtering marker displacement by dragging operations or None for no filter. This function is called each time a marker is diff --git a/silx/gui/plot/backends/BackendMatplotlib.py b/silx/gui/plot/backends/BackendMatplotlib.py index 49c4540..3b1d6dd 100644 --- a/silx/gui/plot/backends/BackendMatplotlib.py +++ b/silx/gui/plot/backends/BackendMatplotlib.py @@ -28,7 +28,7 @@ from __future__ import division __authors__ = ["V.A. Sole", "T. Vincent, H. Payno"] __license__ = "MIT" -__date__ = "18/10/2017" +__date__ = "01/08/2018" import logging @@ -56,8 +56,7 @@ from matplotlib.collections import PathCollection, LineCollection from matplotlib.ticker import Formatter, ScalarFormatter, Locator - -from ..matplotlib.ModestImage import ModestImage +from ....third_party.modest_image import ModestImage from . import BackendBase from .._utils import FLOAT32_MINPOS from .._utils.dtime_ticklayout import calcTicks, bestFormatString, timestamp @@ -520,7 +519,7 @@ class BackendMatplotlib(BackendBase.BackendBase): def addMarker(self, x, y, legend, text, color, selectable, draggable, - symbol, constraint): + symbol, linestyle, linewidth, constraint): legend = "__MARKER__" + legend textArtist = None @@ -548,7 +547,11 @@ class BackendMatplotlib(BackendBase.BackendBase): verticalalignment=valign) elif x is not None: - line = self.ax.axvline(x, label=legend, color=color) + line = self.ax.axvline(x, + label=legend, + color=color, + linewidth=linewidth, + linestyle=linestyle) if text is not None: # Y position will be updated in updateMarkerText call textArtist = self.ax.text(x, 1., " " + text, @@ -557,7 +560,11 @@ class BackendMatplotlib(BackendBase.BackendBase): verticalalignment='top') elif y is not None: - line = self.ax.axhline(y, label=legend, color=color) + line = self.ax.axhline(y, + label=legend, + color=color, + linewidth=linewidth, + linestyle=linestyle) if text is not None: # X position will be updated in updateMarkerText call @@ -1117,7 +1124,6 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): # cursor _QT_CURSORS = { - None: qt.Qt.ArrowCursor, BackendBase.CURSOR_DEFAULT: qt.Qt.ArrowCursor, BackendBase.CURSOR_POINTING: qt.Qt.PointingHandCursor, BackendBase.CURSOR_SIZE_HOR: qt.Qt.SizeHorCursor, @@ -1126,6 +1132,8 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): } def setGraphCursorShape(self, cursor): - cursor = self._QT_CURSORS[cursor] - - FigureCanvasQTAgg.setCursor(self, qt.QCursor(cursor)) + if cursor is None: + FigureCanvasQTAgg.unsetCursor(self) + else: + cursor = self._QT_CURSORS[cursor] + FigureCanvasQTAgg.setCursor(self, qt.QCursor(cursor)) diff --git a/silx/gui/plot/backends/BackendOpenGL.py b/silx/gui/plot/backends/BackendOpenGL.py index 0001bb9..9e2cb73 100644 --- a/silx/gui/plot/backends/BackendOpenGL.py +++ b/silx/gui/plot/backends/BackendOpenGL.py @@ -28,7 +28,7 @@ from __future__ import division __authors__ = ["T. Vincent"] __license__ = "MIT" -__date__ = "24/04/2018" +__date__ = "01/08/2018" from collections import OrderedDict, namedtuple from ctypes import c_void_p @@ -1161,11 +1161,15 @@ class BackendOpenGL(BackendBase.BackendBase, glu.OpenGLWidget): def addMarker(self, x, y, legend, text, color, selectable, draggable, - symbol, constraint): + symbol, linestyle, linewidth, constraint): if symbol is None: symbol = '+' + if linestyle != '-' or linewidth != 1: + _logger.warning( + 'OpenGL backend does not support marker line style and width.') + behaviors = set() if selectable: behaviors.add('selectable') @@ -1223,7 +1227,6 @@ class BackendOpenGL(BackendBase.BackendBase, glu.OpenGLWidget): # Interaction methods _QT_CURSORS = { - None: qt.Qt.ArrowCursor, BackendBase.CURSOR_DEFAULT: qt.Qt.ArrowCursor, BackendBase.CURSOR_POINTING: qt.Qt.PointingHandCursor, BackendBase.CURSOR_SIZE_HOR: qt.Qt.SizeHorCursor, @@ -1232,9 +1235,11 @@ class BackendOpenGL(BackendBase.BackendBase, glu.OpenGLWidget): } def setGraphCursorShape(self, cursor): - cursor = self._QT_CURSORS[cursor] - - super(BackendOpenGL, self).setCursor(qt.QCursor(cursor)) + if cursor is None: + super(BackendOpenGL, self).unsetCursor() + else: + cursor = self._QT_CURSORS[cursor] + super(BackendOpenGL, self).setCursor(qt.QCursor(cursor)) def setGraphCursor(self, flag, color, linewidth, linestyle): if linestyle is not '-': diff --git a/silx/gui/plot/backends/glutils/GLText.py b/silx/gui/plot/backends/glutils/GLText.py index 1540e26..3d262bc 100644 --- a/silx/gui/plot/backends/glutils/GLText.py +++ b/silx/gui/plot/backends/glutils/GLText.py @@ -32,6 +32,7 @@ __license__ = "MIT" __date__ = "03/04/2017" +from collections import OrderedDict import numpy from ...._glutils import font, gl, getGLContext, Program, Texture @@ -41,6 +42,45 @@ from .GLSupport import mat4Translate # TODO: Font should be configurable by the main program: using mpl.rcParams? +class _Cache(object): + """LRU (Least Recent Used) cache. + + :param int maxsize: Maximum number of (key, value) pairs in the cache + :param callable callback: + Called when a (key, value) pair is removed from the cache. + It must take 2 arguments: key and value. + """ + + def __init__(self, maxsize=128, callback=None): + self._maxsize = int(maxsize) + self._callback = callback + self._cache = OrderedDict() + + def __contains__(self, item): + return item in self._cache + + def __getitem__(self, key): + if key in self._cache: + # Remove/add key from ordered dict to store last access info + value = self._cache.pop(key) + self._cache[key] = value + return value + else: + raise KeyError + + def __setitem__(self, key, value): + """Add a key, value pair to the cache. + + :param key: The key to set + :param value: The corresponding value + """ + if key not in self._cache and len(self._cache) >= self._maxsize: + removedKey, removedValue = self._cache.popitem(last=False) + if self._callback is not None: + self._callback(removedKey, removedValue) + self._cache[key] = value + + # Text2D ###################################################################### LEFT, CENTER, RIGHT = 'left', 'center', 'right' @@ -87,11 +127,11 @@ class Text2D(object): _SHADERS['fragment'], attrib0='position') - _textures = {} + # Discard texture objects when removed from the cache + _textures = _Cache(callback=lambda key, value: value[0].discard()) """Cache already created textures""" - # TODO limit cache size and discard least recent used - _sizes = {} + _sizes = _Cache() """Cache already computed sizes""" def __init__(self, text, x=0, y=0, |