class AxisItemScaleFunction(pg.AxisItem):
"""Extension of pyqtgraph AxisItem which allows the axis tick labels to be
transformed using a user-specified function.
Typical use would be to display the same axis data in two different unit
systems. For example, temperature in C and F, or light wavelength as well as
photon energy.
Note that the axis range and scale is not changed, only the calculation of
the axis tick labels."""
def __init__(self, orientation, pen=None, linkView=None, parent=None, maxTickLength=-5, showValues=True, scalefunc=lambda x: x):
self.scalefunc = scalefunc
pg.AxisItem.__init__(self, orientation, pen=pen, linkView=linkView, parent=parent, maxTickLength=maxTickLength, showValues=showValues)
def tickStrings(self, values, scale, spacing):
if self.logMode:
return self.logTickStrings(values, scale, spacing)
warnings.simplefilter("ignore")
try:
places = np.nanmax([0,
np.ceil(-np.log10((np.abs(self.scalefunc(values[0] + spacing) - self.scalefunc(values[0])))*scale)),
np.ceil(-np.log10((np.abs(self.scalefunc(values[-1]) - self.scalefunc(values[-1] - spacing)))*scale))])
except IndexError:
places = 0
warnings.simplefilter("default")
strings = []
for v in values:
vs = self.scalefunc(v) * scale
if abs(vs) < .001 or abs(vs) >= 10000:
vstr = "%g" % vs
else:
vstr = ("%%0.%df" % places) % vs
strings.append(vstr)
return strings
def updateAutoSIPrefix(self):
if self.label.isVisible():
(scale, prefix) = pg.siScale(max(abs(self.scalefunc(self.range[0])), abs(self.scalefunc(self.range[1]))))
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 logTickStrings(self, values, scale, spacing):
return ["%0.1g"%x for x in 10 ** np.array(self.scalefunc(values)).astype(float)]