# -*- coding: utf-8 -*-
#
# Licensed under the terms of the Qwt License
# Copyright (c) 2002 Uwe Rathmann, for the original C++ code
# Copyright (c) 2015 Pierre Raybaut, for the Python translation/optimization
# (see LICENSE file for more details)
"""
QwtScaleDiv
-----------
.. autoclass:: QwtScaleDiv
:members:
"""
from qwt.interval import QwtInterval
import copy
[docs]class QwtScaleDiv(object):
"""
A class representing a scale division
A Qwt scale is defined by its boundaries and 3 list
for the positions of the major, medium and minor ticks.
The `upperLimit()` might be smaller than the `lowerLimit()`
to indicate inverted scales.
Scale divisions can be calculated from a `QwtScaleEngine`.
.. seealso::
:py:meth:`qwt.scale_engine.QwtScaleEngine.divideScale()`,
:py:meth:`qwt.plot.QwtPlot.setAxisScaleDiv()`
Scale tick types:
* `QwtScaleDiv.NoTick`: No ticks
* `QwtScaleDiv.MinorTick`: Minor ticks
* `QwtScaleDiv.MediumTick`: Medium ticks
* `QwtScaleDiv.MajorTick`: Major ticks
* `QwtScaleDiv.NTickTypes`: Number of valid tick types
.. py:class:: QwtScaleDiv()
Basic constructor. Lower bound = Upper bound = 0.
.. py:class:: QwtScaleDiv(interval, ticks)
:param qwt.interval.QwtInterval interval: Interval
:param list ticks: list of major, medium and minor ticks
.. py:class:: QwtScaleDiv(lowerBound, upperBound)
:param float lowerBound: First boundary
:param float upperBound: Second boundary
.. py:class:: QwtScaleDiv(lowerBound, upperBound, ticks)
:param float lowerBound: First boundary
:param float upperBound: Second boundary
:param list ticks: list of major, medium and minor ticks
.. py:class:: QwtScaleDiv(lowerBound, upperBound, minorTicks, mediumTicks, majorTicks)
:param float lowerBound: First boundary
:param float upperBound: Second boundary
:param list minorTicks: list of minor ticks
:param list mediumTicks: list of medium ticks
:param list majorTicks: list of major ticks
.. note::
lowerBound might be greater than upperBound for inverted scales
"""
# enum TickType
NoTick = -1
MinorTick, MediumTick, MajorTick, NTickTypes = list(range(4))
def __init__(self, *args):
self.__ticks = None
if len(args) == 2 and isinstance(args[1], (tuple, list)):
interval, ticks = args
self.__lowerBound = interval.minValue()
self.__upperBound = interval.maxValue()
self.__ticks = ticks[:]
elif len(args) == 2:
self.__lowerBound, self.__upperBound = args
elif len(args) == 3:
self.__lowerBound, self.__upperBound, ticks = args
self.__ticks = ticks[:]
elif len(args) == 5:
(self.__lowerBound, self.__upperBound,
minorTicks, mediumTicks, majorTicks) = args
self.__ticks[self.MinorTick] = minorTicks
self.__ticks[self.MediumTick] = mediumTicks
self.__ticks[self.MajorTick] = majorTicks
elif len(args) == 0:
self.__lowerBound, self.__upperBound = 0., 0.
else:
raise TypeError("%s() takes 0, 2, 3 or 5 argument(s) (%s given)"\
% (self.__class__.__name__, len(args)))
[docs] def setInterval(self, *args):
"""
Change the interval
.. py:method:: setInterval(lowerBound, upperBound)
:param float lowerBound: First boundary
:param float upperBound: Second boundary
.. py:method:: setInterval(interval)
:param qwt.interval.QwtInterval interval: Interval
.. note::
lowerBound might be greater than upperBound for inverted scales
"""
if len(args) == 2:
self.__lowerBound, self.__upperBound = args
elif len(args) == 1:
interval, = args
self.__lowerBound = interval.minValue()
self.__upperBound = interval.maxValue()
else:
raise TypeError("%s().setInterval() takes 1 or 2 argument(s) (%s "\
"given)" % (self.__class__.__name__, len(args)))
[docs] def interval(self):
"""
:return: Interval
"""
return QwtInterval(self.__lowerBound, self.__upperBound)
[docs] def setLowerBound(self, lowerBound):
"""
Set the first boundary
:param float lowerBound: First boundary
.. seealso::
:py:meth:`lowerBound()`, :py:meth:`setUpperBound()`
"""
self.__lowerBound = lowerBound
[docs] def lowerBound(self):
"""
:return: the first boundary
.. seealso::
:py:meth:`upperBound()`
"""
return self.__lowerBound
[docs] def setUpperBound(self, upperBound):
"""
Set the second boundary
:param float lowerBound: Second boundary
.. seealso::
:py:meth:`upperBound()`, :py:meth:`setLowerBound()`
"""
self.__upperBound = upperBound
[docs] def upperBound(self):
"""
:return: the second boundary
.. seealso::
:py:meth:`lowerBound()`
"""
return self.__upperBound
[docs] def range(self):
"""
:return: upperBound() - lowerBound()
"""
return self.__upperBound - self.__lowerBound
def __eq__(self, other):
if self.__ticks is None:
return False
if self.__lowerBound != other.__lowerBound or\
self.__upperBound != other.__upperBound:
return False
return self.__ticks == other.__ticks
def __ne__(self, other):
return not self.__eq__(other)
[docs] def isEmpty(self):
"""
Check if the scale division is empty( lowerBound() == upperBound() )
"""
return self.__lowerBound == self.__upperBound
[docs] def isIncreasing(self):
"""
Check if the scale division is increasing( lowerBound() <= upperBound() )
"""
return self.__lowerBound <= self.__upperBound
[docs] def contains(self, value):
"""
Return if a value is between lowerBound() and upperBound()
:param float value: Value
:return: True/False
"""
min_ = min([self.__lowerBound, self.__upperBound])
max_ = max([self.__lowerBound, self.__upperBound])
return value >= min_ and value <= max_
[docs] def invert(self):
"""
Invert the scale division
.. seealso::
:py:meth:`inverted()`
"""
(self.__lowerBound,
self.__upperBound) = self.__upperBound, self.__lowerBound
for index in range(self.NTickTypes):
self.__ticks[index].reverse()
[docs] def inverted(self):
"""
:return: A scale division with inverted boundaries and ticks
.. seealso::
:py:meth:`invert()`
"""
other = copy.deepcopy(self)
other.invert()
return other
[docs] def bounded(self, lowerBound, upperBound):
"""
Return a scale division with an interval [lowerBound, upperBound]
where all ticks outside this interval are removed
:param float lowerBound: First boundary
:param float lowerBound: Second boundary
:return: Scale division with all ticks inside of the given interval
.. note::
lowerBound might be greater than upperBound for inverted scales
"""
min_ = min([self.__lowerBound, self.__upperBound])
max_ = max([self.__lowerBound, self.__upperBound])
sd = QwtScaleDiv()
sd.setInterval(lowerBound, upperBound)
for tickType in range(self.NTickTypes):
sd.setTicks(tickType, [tick for tick in self.__ticks[tickType]
if tick >= min_ and tick <= max_])
return sd
[docs] def setTicks(self, tickType, ticks):
"""
Assign ticks
:param int type: MinorTick, MediumTick or MajorTick
:param list ticks: Values of the tick positions
"""
if tickType in range(self.NTickTypes):
self.__ticks[tickType] = ticks
[docs] def ticks(self, tickType):
"""
Return a list of ticks
:param int type: MinorTick, MediumTick or MajorTick
:return: Tick list
"""
if self.__ticks is not None and tickType in range(self.NTickTypes):
return self.__ticks[tickType]
else:
return []