From 22ecd3cc414ab6e42c6f750bdd592e616fed7072 Mon Sep 17 00:00:00 2001 From: JosefNevrly Date: Sun, 16 Mar 2014 10:20:42 +0100 Subject: [PATCH 1/3] PlotItem.showValues fixed (was not implemented before). --- pyqtgraph/graphicsItems/AxisItem.py | 166 ++++++++++++++-------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py index 001ee2cf..5ebd8a50 100644 --- a/pyqtgraph/graphicsItems/AxisItem.py +++ b/pyqtgraph/graphicsItems/AxisItem.py @@ -775,92 +775,92 @@ class AxisItem(GraphicsWidget): textSize2 = 0 textRects = [] textSpecs = [] ## list of draw - textSize2 = 0 - for i in range(len(tickLevels)): - ## Get the list of strings to display for this level - if tickStrings is None: - spacing, values = tickLevels[i] - strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing) - else: - strings = tickStrings[i] - - if len(strings) == 0: - continue - - ## ignore strings belonging to ticks that were previously ignored - for j in range(len(strings)): - if tickPositions[i][j] is None: - strings[j] = None - - ## Measure density of text; decide whether to draw this level - rects = [] - for s in strings: - if s is None: - rects.append(None) + if self.showValues: + for i in range(len(tickLevels)): + ## Get the list of strings to display for this level + if tickStrings is None: + spacing, values = tickLevels[i] + strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing) else: - br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s)) - ## boundingRect is usually just a bit too large - ## (but this probably depends on per-font metrics?) - br.setHeight(br.height() * 0.8) + strings = tickStrings[i] - rects.append(br) - textRects.append(rects[-1]) - - if i > 0: ## always draw top level - ## measure all text, make sure there's enough room - if axis == 0: - textSize = np.sum([r.height() for r in textRects]) - textSize2 = np.max([r.width() for r in textRects]) if textRects else 0 - else: - textSize = np.sum([r.width() for r in textRects]) - textSize2 = np.max([r.height() for r in textRects]) if textRects else 0 - - ## If the strings are too crowded, stop drawing text now. - ## We use three different crowding limits based on the number - ## of texts drawn so far. - textFillRatio = float(textSize) / lengthInPixels - finished = False - for nTexts, limit in self.style['textFillLimits']: - if len(textSpecs) >= nTexts and textFillRatio >= limit: - finished = True - break - if finished: - break - - #spacing, values = tickLevels[best] - #strings = self.tickStrings(values, self.scale, spacing) - for j in range(len(strings)): - vstr = strings[j] - if vstr is None: ## this tick was ignored because it is out of bounds + if len(strings) == 0: continue - vstr = asUnicode(vstr) - x = tickPositions[i][j] - #textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr) - textRect = rects[j] - height = textRect.height() - width = textRect.width() - #self.textHeight = height - offset = max(0,self.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) - elif self.orientation == 'right': - textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter - rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height) - elif self.orientation == 'top': - textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom - rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height) - elif self.orientation == 'bottom': - textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop - rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height) - - #p.setPen(self.pen()) - #p.drawText(rect, textFlags, vstr) - textSpecs.append((rect, textFlags, vstr)) - profiler('compute text') - - ## update max text size if needed. - self._updateMaxTextSize(textSize2) + + ## ignore strings belonging to ticks that were previously ignored + for j in range(len(strings)): + if tickPositions[i][j] is None: + strings[j] = None + + ## Measure density of text; decide whether to draw this level + rects = [] + for s in strings: + if s is None: + rects.append(None) + else: + br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s)) + ## boundingRect is usually just a bit too large + ## (but this probably depends on per-font metrics?) + br.setHeight(br.height() * 0.8) + + rects.append(br) + textRects.append(rects[-1]) + + if i > 0: ## always draw top level + ## measure all text, make sure there's enough room + if axis == 0: + textSize = np.sum([r.height() for r in textRects]) + textSize2 = np.max([r.width() for r in textRects]) if textRects else 0 + else: + textSize = np.sum([r.width() for r in textRects]) + textSize2 = np.max([r.height() for r in textRects]) if textRects else 0 + + ## If the strings are too crowded, stop drawing text now. + ## We use three different crowding limits based on the number + ## of texts drawn so far. + textFillRatio = float(textSize) / lengthInPixels + finished = False + for nTexts, limit in self.style['textFillLimits']: + if len(textSpecs) >= nTexts and textFillRatio >= limit: + finished = True + break + if finished: + break + + #spacing, values = tickLevels[best] + #strings = self.tickStrings(values, self.scale, spacing) + for j in range(len(strings)): + vstr = strings[j] + if vstr is None: ## this tick was ignored because it is out of bounds + continue + vstr = asUnicode(vstr) + x = tickPositions[i][j] + #textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr) + textRect = rects[j] + height = textRect.height() + width = textRect.width() + #self.textHeight = height + offset = max(0,self.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) + elif self.orientation == 'right': + textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter + rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height) + elif self.orientation == 'top': + textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom + rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height) + elif self.orientation == 'bottom': + textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop + rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height) + + #p.setPen(self.pen()) + #p.drawText(rect, textFlags, vstr) + textSpecs.append((rect, textFlags, vstr)) + profiler('compute text') + + ## update max text size if needed. + self._updateMaxTextSize(textSize2) return (axisSpec, tickSpecs, textSpecs) From aa4b790dd290d5c5002e092a999c12251ed41ab8 Mon Sep 17 00:00:00 2001 From: JosefNevrly Date: Sun, 16 Mar 2014 10:38:08 +0100 Subject: [PATCH 2/3] Fixes calculation of axis width/height in case values are not shown. --- pyqtgraph/graphicsItems/AxisItem.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py index 5ebd8a50..703662e4 100644 --- a/pyqtgraph/graphicsItems/AxisItem.py +++ b/pyqtgraph/graphicsItems/AxisItem.py @@ -242,10 +242,12 @@ class AxisItem(GraphicsWidget): """Set the height of this axis reserved for ticks and tick labels. The height of the axis label is automatically added.""" if h is None: - if self.style['autoExpandTextSpace'] is True: - h = self.textHeight - else: - h = self.style['tickTextHeight'] + h = 0 + if self.showValues: + if self.style['autoExpandTextSpace'] is True: + h = self.textHeight + else: + h = self.style['tickTextHeight'] h += max(0, self.tickLength) + self.style['tickTextOffset'][1] if self.label.isVisible(): h += self.label.boundingRect().height() * 0.8 @@ -258,10 +260,12 @@ class AxisItem(GraphicsWidget): """Set the width of this axis reserved for ticks and tick labels. The width of the axis label is automatically added.""" if w is None: - if self.style['autoExpandTextSpace'] is True: - w = self.textWidth - else: - w = self.style['tickTextWidth'] + w = 0 + if self.showValues: + if self.style['autoExpandTextSpace'] is True: + w = self.textWidth + else: + w = self.style['tickTextWidth'] w += max(0, self.tickLength) + self.style['tickTextOffset'][0] if self.label.isVisible(): w += self.label.boundingRect().height() * 0.8 ## bounding rect is usually an overestimate @@ -859,8 +863,8 @@ class AxisItem(GraphicsWidget): textSpecs.append((rect, textFlags, vstr)) profiler('compute text') - ## update max text size if needed. - self._updateMaxTextSize(textSize2) + ## update max text size if needed. + self._updateMaxTextSize(textSize2) return (axisSpec, tickSpecs, textSpecs) From 26c57a0f14cf4ba3b2f2600165c9749988206107 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sat, 29 Mar 2014 11:31:23 -0400 Subject: [PATCH 3/3] Style changes and a minor bug fix --- pyqtgraph/graphicsItems/AxisItem.py | 198 ++++++++++---------- pyqtgraph/graphicsItems/HistogramLUTItem.py | 2 +- 2 files changed, 102 insertions(+), 98 deletions(-) diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py index 703662e4..e1cf1c4c 100644 --- a/pyqtgraph/graphicsItems/AxisItem.py +++ b/pyqtgraph/graphicsItems/AxisItem.py @@ -33,7 +33,6 @@ class AxisItem(GraphicsWidget): GraphicsWidget.__init__(self, parent) self.label = QtGui.QGraphicsTextItem(self) - self.showValues = showValues self.picture = None self.orientation = orientation if orientation not in ['left', 'right', 'top', 'bottom']: @@ -53,7 +52,8 @@ class AxisItem(GraphicsWidget): (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': showValues, } self.textWidth = 30 ## Keeps track of maximum width / height of tick text @@ -242,31 +242,31 @@ class AxisItem(GraphicsWidget): """Set the height of this axis reserved for ticks and tick labels. The height of the axis label is automatically added.""" if h is None: - h = 0 - if self.showValues: - if self.style['autoExpandTextSpace'] is True: - h = self.textHeight - else: - h = self.style['tickTextHeight'] - h += max(0, self.tickLength) + self.style['tickTextOffset'][1] + if not self.style['showValues']: + h = 0 + elif self.style['autoExpandTextSpace'] is True: + 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 if self.label.isVisible(): h += self.label.boundingRect().height() * 0.8 self.setMaximumHeight(h) self.setMinimumHeight(h) self.picture = None - def setWidth(self, w=None): """Set the width of this axis reserved for ticks and tick labels. The width of the axis label is automatically added.""" if w is None: - w = 0 - if self.showValues: - if self.style['autoExpandTextSpace'] is True: - w = self.textWidth - else: - w = self.style['tickTextWidth'] - w += max(0, self.tickLength) + self.style['tickTextOffset'][0] + if not self.style['showValues']: + w = 0 + elif self.style['autoExpandTextSpace'] is True: + w = self.textWidth + else: + w = self.style['tickTextWidth'] + textOffset = self.style['tickTextOffset'][0] if self.style['showValues'] else 0 if self.label.isVisible(): w += self.label.boundingRect().height() * 0.8 ## bounding rect is usually an overestimate self.setMaximumWidth(w) @@ -779,89 +779,93 @@ class AxisItem(GraphicsWidget): textSize2 = 0 textRects = [] textSpecs = [] ## list of draw - if self.showValues: - for i in range(len(tickLevels)): - ## Get the list of strings to display for this level - if tickStrings is None: - spacing, values = tickLevels[i] - strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing) + + # If values are hidden, return early + if not self.style['showValues']: + return (axisSpec, tickSpecs, textSpecs) + + for i in range(len(tickLevels)): + ## Get the list of strings to display for this level + if tickStrings is None: + spacing, values = tickLevels[i] + strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing) + else: + strings = tickStrings[i] + + if len(strings) == 0: + continue + + ## ignore strings belonging to ticks that were previously ignored + for j in range(len(strings)): + if tickPositions[i][j] is None: + strings[j] = None + + ## Measure density of text; decide whether to draw this level + rects = [] + for s in strings: + if s is None: + rects.append(None) else: - strings = tickStrings[i] + br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s)) + ## boundingRect is usually just a bit too large + ## (but this probably depends on per-font metrics?) + br.setHeight(br.height() * 0.8) - if len(strings) == 0: - continue - - ## ignore strings belonging to ticks that were previously ignored - for j in range(len(strings)): - if tickPositions[i][j] is None: - strings[j] = None - - ## Measure density of text; decide whether to draw this level - rects = [] - for s in strings: - if s is None: - rects.append(None) - else: - br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s)) - ## boundingRect is usually just a bit too large - ## (but this probably depends on per-font metrics?) - br.setHeight(br.height() * 0.8) - - rects.append(br) - textRects.append(rects[-1]) - - if i > 0: ## always draw top level - ## measure all text, make sure there's enough room - if axis == 0: - textSize = np.sum([r.height() for r in textRects]) - textSize2 = np.max([r.width() for r in textRects]) if textRects else 0 - else: - textSize = np.sum([r.width() for r in textRects]) - textSize2 = np.max([r.height() for r in textRects]) if textRects else 0 - - ## If the strings are too crowded, stop drawing text now. - ## We use three different crowding limits based on the number - ## of texts drawn so far. - textFillRatio = float(textSize) / lengthInPixels - finished = False - for nTexts, limit in self.style['textFillLimits']: - if len(textSpecs) >= nTexts and textFillRatio >= limit: - finished = True - break - if finished: + rects.append(br) + textRects.append(rects[-1]) + + if i > 0: ## always draw top level + ## measure all text, make sure there's enough room + if axis == 0: + textSize = np.sum([r.height() for r in textRects]) + textSize2 = np.max([r.width() for r in textRects]) if textRects else 0 + else: + textSize = np.sum([r.width() for r in textRects]) + textSize2 = np.max([r.height() for r in textRects]) if textRects else 0 + + ## If the strings are too crowded, stop drawing text now. + ## We use three different crowding limits based on the number + ## of texts drawn so far. + textFillRatio = float(textSize) / lengthInPixels + finished = False + for nTexts, limit in self.style['textFillLimits']: + if len(textSpecs) >= nTexts and textFillRatio >= limit: + finished = True break - - #spacing, values = tickLevels[best] - #strings = self.tickStrings(values, self.scale, spacing) - for j in range(len(strings)): - vstr = strings[j] - if vstr is None: ## this tick was ignored because it is out of bounds - continue - vstr = asUnicode(vstr) - x = tickPositions[i][j] - #textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr) - textRect = rects[j] - height = textRect.height() - width = textRect.width() - #self.textHeight = height - offset = max(0,self.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) - elif self.orientation == 'right': - textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter - rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height) - elif self.orientation == 'top': - textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom - rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height) - elif self.orientation == 'bottom': - textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop - rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height) - - #p.setPen(self.pen()) - #p.drawText(rect, textFlags, vstr) - textSpecs.append((rect, textFlags, vstr)) - profiler('compute text') + if finished: + break + + #spacing, values = tickLevels[best] + #strings = self.tickStrings(values, self.scale, spacing) + for j in range(len(strings)): + vstr = strings[j] + if vstr is None: ## this tick was ignored because it is out of bounds + continue + vstr = asUnicode(vstr) + x = tickPositions[i][j] + #textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr) + textRect = rects[j] + height = textRect.height() + width = textRect.width() + #self.textHeight = height + offset = max(0,self.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) + elif self.orientation == 'right': + textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter + rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height) + elif self.orientation == 'top': + textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom + rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height) + elif self.orientation == 'bottom': + textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop + rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height) + + #p.setPen(self.pen()) + #p.drawText(rect, textFlags, vstr) + textSpecs.append((rect, textFlags, vstr)) + profiler('compute text') ## update max text size if needed. self._updateMaxTextSize(textSize2) diff --git a/pyqtgraph/graphicsItems/HistogramLUTItem.py b/pyqtgraph/graphicsItems/HistogramLUTItem.py index 8474202c..71577422 100644 --- a/pyqtgraph/graphicsItems/HistogramLUTItem.py +++ b/pyqtgraph/graphicsItems/HistogramLUTItem.py @@ -58,7 +58,7 @@ class HistogramLUTItem(GraphicsWidget): self.region = LinearRegionItem([0, 1], LinearRegionItem.Horizontal) self.region.setZValue(1000) self.vb.addItem(self.region) - self.axis = AxisItem('left', linkView=self.vb, maxTickLength=-10, showValues=False) + self.axis = AxisItem('left', linkView=self.vb, maxTickLength=-10) self.layout.addItem(self.axis, 0, 0) self.layout.addItem(self.vb, 0, 1) self.layout.addItem(self.gradient, 0, 2)