diff --git a/CHANGELOG b/CHANGELOG index b0df0b13..0db2cf82 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -45,6 +45,7 @@ pyqtgraph-0.9.9 [unreleased] - Multiprocess debugging colors messages by process - Stdout filter that colors text by thread - PeriodicTrace used to report deadlocks + - Added AxisItem.setStyle() Bugfixes: - PlotCurveItem now has correct clicking behavior--clicks within a few px diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py index e1cf1c4c..bbf59571 100644 --- a/pyqtgraph/graphicsItems/AxisItem.py +++ b/pyqtgraph/graphicsItems/AxisItem.py @@ -41,7 +41,7 @@ class AxisItem(GraphicsWidget): self.label.rotate(-90) self.style = { - 'tickTextOffset': (5, 2), ## (horizontal, vertical) spacing between text and axis + 'tickTextOffset': [5, 2], ## (horizontal, vertical) spacing between text and axis 'tickTextWidth': 30, ## space reserved for tick text 'tickTextHeight': 18, 'autoExpandTextSpace': True, ## automatically expand text space if needed @@ -54,6 +54,7 @@ class AxisItem(GraphicsWidget): (6, 0.2), ## If we already have 6 ticks with text, fill no more than 20% of the axis ], 'showValues': showValues, + 'tickLength': maxTickLength, } self.textWidth = 30 ## Keeps track of maximum width / height of tick text @@ -66,7 +67,6 @@ class AxisItem(GraphicsWidget): self.logMode = False self.tickFont = None - self.tickLength = maxTickLength self._tickLevels = None ## used to override the automatic ticking system with explicit ticks self.scale = 1.0 self.autoSIPrefix = True @@ -87,6 +87,71 @@ class AxisItem(GraphicsWidget): self.grid = False #self.setCacheMode(self.DeviceCoordinateCache) + + def setStyle(self, **kwds): + """ + Set various style options. + + =================== ======================================================= + Keyword Arguments: + tickLength (int) The maximum length of ticks in pixels. + Positive values point toward the text; negative + values point away. + tickTextOffset (int) reserved spacing between text and axis in px + tickTextWidth (int) Horizontal space reserved for tick text in px + tickTextHeight (int) Vertical space reserved for tick text in px + autoExpandTextSpace (bool) Automatically expand text space if the tick + strings become too long. + tickFont (QFont or None) Determines the font used for tick + values. Use None for the default font. + stopAxisAtTick (tuple: (bool min, bool max)) If True, the axis + line is drawn only as far as the last tick. + Otherwise, the line is drawn to the edge of the + AxisItem boundary. + textFillLimits (list of (tick #, % fill) tuples). This structure + determines how the AxisItem decides how many ticks + should have text appear next to them. Each tuple in + the list specifies what fraction of the axis length + may be occupied by text, given the number of ticks + that already have text displayed. For example:: + + [(0, 0.8), # Never fill more than 80% of the axis + (2, 0.6), # If we already have 2 ticks with text, + # fill no more than 60% of the axis + (4, 0.4), # If we already have 4 ticks with text, + # fill no more than 40% of the axis + (6, 0.2)] # If we already have 6 ticks with text, + # fill no more than 20% of the axis + + showValues (bool) indicates whether text is displayed adjacent + to ticks. + =================== ======================================================= + """ + for kwd,value in kwds.items(): + if kwd not in self.style: + raise NameError("%s is not a valid style argument." % kwd) + + if kwd in ('tickLength', 'tickTextOffset', 'tickTextWidth', 'tickTextHeight'): + if not isinstance(value, int): + raise ValueError("Argument '%s' must be int" % kwd) + + if kwd == 'tickTextOffset': + if self.orientation in ('left', 'right'): + self.style['tickTextOffset'][0] = value + else: + self.style['tickTextOffset'][1] = value + elif kwd == 'stopAxisAtTick': + try: + assert len(value) == 2 and isinstance(value[0], bool) and isinstance(value[1], bool) + except: + raise ValueError("Argument 'stopAxisAtTick' must have type (bool, bool)") + self.style[kwd] = value + else: + self.style[kwd] = value + + self.picture = None + self._adjustSize() + self.update() def close(self): self.scene().removeItem(self.label) @@ -128,20 +193,15 @@ class AxisItem(GraphicsWidget): if self.orientation == 'left': p.setY(int(self.size().height()/2 + br.width()/2)) p.setX(-nudge) - #s.setWidth(10) elif self.orientation == 'right': - #s.setWidth(10) p.setY(int(self.size().height()/2 + br.width()/2)) p.setX(int(self.size().width()-br.height()+nudge)) elif self.orientation == 'top': - #s.setHeight(10) p.setY(-nudge) p.setX(int(self.size().width()/2. - br.width()/2.)) elif self.orientation == 'bottom': p.setX(int(self.size().width()/2. - br.width()/2.)) - #s.setHeight(10) p.setY(int(self.size().height()-br.height()+nudge)) - #self.label.resize(s) self.label.setPos(p) self.picture = None @@ -167,7 +227,7 @@ class AxisItem(GraphicsWidget): without any scaling prefix (eg, 'V' instead of 'mV'). The scaling prefix will be automatically prepended based on the range of data displayed. - \**args All extra keyword arguments become CSS style options for + **args All extra keyword arguments become CSS style options for the tag which will surround the axis label and units. ============== ============================================================= @@ -248,8 +308,8 @@ class AxisItem(GraphicsWidget): h = self.textHeight else: h = self.style['tickTextHeight'] - textOffset = self.style['tickTextOffset'][1] if self.style['showValues'] else 0 - h += max(0, self.tickLength) + textOffset + h += self.style['tickTextOffset'][1] if self.style['showValues'] else 0 + h += max(0, self.style['tickLength']) if self.label.isVisible(): h += self.label.boundingRect().height() * 0.8 self.setMaximumHeight(h) @@ -266,7 +326,8 @@ class AxisItem(GraphicsWidget): w = self.textWidth else: w = self.style['tickTextWidth'] - textOffset = self.style['tickTextOffset'][0] if self.style['showValues'] else 0 + w += self.style['tickTextOffset'][0] if self.style['showValues'] else 0 + w += max(0, self.style['tickLength']) if self.label.isVisible(): w += self.label.boundingRect().height() * 0.8 ## bounding rect is usually an overestimate self.setMaximumWidth(w) @@ -399,14 +460,15 @@ class AxisItem(GraphicsWidget): rect = self.mapRectFromParent(self.geometry()) ## extend rect if ticks go in negative direction ## also extend to account for text that flows past the edges + tl = self.style['tickLength'] if self.orientation == 'left': - rect = rect.adjusted(0, -15, -min(0,self.tickLength), 15) + rect = rect.adjusted(0, -15, -min(0,tl), 15) elif self.orientation == 'right': - rect = rect.adjusted(min(0,self.tickLength), -15, 0, 15) + rect = rect.adjusted(min(0,tl), -15, 0, 15) elif self.orientation == 'top': - rect = rect.adjusted(-15, 0, 15, -min(0,self.tickLength)) + rect = rect.adjusted(-15, 0, 15, -min(0,tl)) elif self.orientation == 'bottom': - rect = rect.adjusted(-15, min(0,self.tickLength), 15, 0) + rect = rect.adjusted(-15, min(0,tl), 15, 0) return rect else: return self.mapRectFromParent(self.geometry()) | linkedView.mapRectToItem(self, linkedView.boundingRect()) @@ -723,7 +785,7 @@ class AxisItem(GraphicsWidget): ticks = tickLevels[i][1] ## length of tick - tickLength = self.tickLength / ((i*0.5)+1.0) + tickLength = self.style['tickLength'] / ((i*0.5)+1.0) lineAlpha = 255 / (i+1) if self.grid is not False: @@ -848,7 +910,7 @@ class AxisItem(GraphicsWidget): height = textRect.height() width = textRect.width() #self.textHeight = height - offset = max(0,self.tickLength) + textOffset + offset = max(0,self.style['tickLength']) + textOffset if self.orientation == 'left': textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter rect = QtCore.QRectF(tickStop-offset-width, x-(height/2), width, height)