Fixed improper tick spacing and axis scaling

This requires an API change:
 - AxisItem.setScale(float) has the usual behavior
 - AxisItem.setScale(None) is no longer allowed. Instead use:
 - AxisItem.enableAutoSIPrefix(bool) to enable/disable SI prefix scaling
Also makes the API more intuitive since these features are now accessed and implemented independently.
This commit is contained in:
Luke Campagnola 2013-10-18 14:47:49 -04:00
parent ea6f4ef442
commit 390f78c810

View File

@ -69,7 +69,8 @@ class AxisItem(GraphicsWidget):
self.tickLength = maxTickLength self.tickLength = maxTickLength
self._tickLevels = None ## used to override the automatic ticking system with explicit ticks self._tickLevels = None ## used to override the automatic ticking system with explicit ticks
self.scale = 1.0 self.scale = 1.0
self.autoScale = True self.autoSIPrefix = True
self.autoSIPrefixScale = 1.0
self.setRange(0, 1) self.setRange(0, 1)
@ -149,8 +150,8 @@ class AxisItem(GraphicsWidget):
self.setWidth() self.setWidth()
else: else:
self.setHeight() self.setHeight()
if self.autoScale: if self.autoSIPrefix:
self.setScale() self.updateAutoSIPrefix()
def setLabel(self, text=None, units=None, unitPrefix=None, **args): def setLabel(self, text=None, units=None, unitPrefix=None, **args):
"""Set the text displayed adjacent to the axis. """Set the text displayed adjacent to the axis.
@ -195,10 +196,10 @@ class AxisItem(GraphicsWidget):
def labelString(self): def labelString(self):
if self.labelUnits == '': if self.labelUnits == '':
if self.scale == 1.0: if not self.autoSIPrefix or self.autoSIPrefixScale == 1.0:
units = '' units = ''
else: else:
units = asUnicode('(x%g)') % (1.0/self.scale) units = asUnicode('(x%g)') % (1.0/self.autoSIPrefixScale)
else: else:
#print repr(self.labelUnitPrefix), repr(self.labelUnits) #print repr(self.labelUnitPrefix), repr(self.labelUnits)
units = asUnicode('(%s%s)') % (self.labelUnitPrefix, self.labelUnits) units = asUnicode('(%s%s)') % (self.labelUnitPrefix, self.labelUnits)
@ -295,22 +296,22 @@ class AxisItem(GraphicsWidget):
to 'V' then a scale of 1000 would cause the axis to display values -100 to 100 to 'V' then a scale of 1000 would cause the axis to display values -100 to 100
and the units would appear as 'mV' and the units would appear as 'mV'
""" """
if scale is None: #if scale is None:
#if self.drawLabel: ## If there is a label, then we are free to rescale the values ##if self.drawLabel: ## If there is a label, then we are free to rescale the values
if self.label.isVisible(): #if self.label.isVisible():
#d = self.range[1] - self.range[0] ##d = self.range[1] - self.range[0]
#(scale, prefix) = fn.siScale(d / 2.) ##(scale, prefix) = fn.siScale(d / 2.)
(scale, prefix) = fn.siScale(max(abs(self.range[0]), abs(self.range[1]))) #(scale, prefix) = fn.siScale(max(abs(self.range[0]), abs(self.range[1])))
if self.labelUnits == '' and prefix in ['k', 'm']: ## If we are not showing units, wait until 1e6 before scaling. #if self.labelUnits == '' and prefix in ['k', 'm']: ## If we are not showing units, wait until 1e6 before scaling.
scale = 1.0 #scale = 1.0
prefix = '' #prefix = ''
self.setLabel(unitPrefix=prefix) #self.setLabel(unitPrefix=prefix)
else: #else:
scale = 1.0 #scale = 1.0
self.autoScale = True #self.autoScale = True
else: #else:
self.setLabel(unitPrefix='') #self.setLabel(unitPrefix='')
self.autoScale = False #self.autoScale = False
if scale != self.scale: if scale != self.scale:
self.scale = scale self.scale = scale
@ -318,14 +319,32 @@ class AxisItem(GraphicsWidget):
self.picture = None self.picture = None
self.update() self.update()
def enableAutoSIPrefix(self, enable=True):
self.autoSIPrefix = enable
def updateAutoSIPrefix(self):
if self.label.isVisible():
(scale, prefix) = fn.siScale(max(abs(self.range[0]*self.scale), abs(self.range[1]*self.scale)))
if self.labelUnits == '' and prefix in ['k', 'm']: ## If we are not showing units, wait until 1e6 before scaling.
scale = 1.0
prefix = ''
self.setLabel(unitPrefix=prefix)
else:
scale = 1.0
self.autoSIPrefixScale = scale
self.picture = None
self.update()
def setRange(self, mn, mx): def setRange(self, mn, mx):
"""Set the range of values displayed by the axis. """Set the range of values displayed by the axis.
Usually this is handled automatically by linking the axis to a ViewBox with :func:`linkToView <pyqtgraph.AxisItem.linkToView>`""" Usually this is handled automatically by linking the axis to a ViewBox with :func:`linkToView <pyqtgraph.AxisItem.linkToView>`"""
if any(np.isinf((mn, mx))) or any(np.isnan((mn, mx))): if any(np.isinf((mn, mx))) or any(np.isnan((mn, mx))):
raise Exception("Not setting range to [%s, %s]" % (str(mn), str(mx))) raise Exception("Not setting range to [%s, %s]" % (str(mn), str(mx)))
self.range = [mn, mx] self.range = [mn, mx]
if self.autoScale: if self.autoSIPrefix:
self.setScale() self.updateAutoSIPrefix()
self.picture = None self.picture = None
self.update() self.update()
@ -756,7 +775,7 @@ class AxisItem(GraphicsWidget):
## Get the list of strings to display for this level ## Get the list of strings to display for this level
if tickStrings is None: if tickStrings is None:
spacing, values = tickLevels[i] spacing, values = tickLevels[i]
strings = self.tickStrings(values, self.scale, spacing) strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing)
else: else:
strings = tickStrings[i] strings = tickStrings[i]