From e7ceebd867de04c66cf227a0e63dd7dbbc18cab0 Mon Sep 17 00:00:00 2001 From: Drew Date: Sat, 6 Feb 2021 02:00:34 -0500 Subject: [PATCH] LegendItem: fix docs & minor bugs (#1437) * LegendItem: fix spelling mistake * LegendItem: remove unused curRow variable * LegendItem: correct calculation of rowCount Previously, rowCount would never be updated unless setColumnCount() was called. This fixes that issue. It also fixes that setColumnCount() rounded down (floored) the number of rows, instead of providing an accurate number: e.g. 4 items in 3 columns would yield rowCount=1, when it should be 2 * LegendItem: remove rowCount argument (not implemented) Logic to actually use the rowCount argument was not implemented. Users might expect rowCount to limit the number of rows to e.g. 1, but that is not what the current code does (it only works with limiting the number of columns). Thus, we were exposing an unused/misleading parameter to users. This can and should be reverted if the logic for limiting the number of rows is added. * LegendItem: add colCount docs * test (LegendItem): remove unused curRow variable * test (LegendItem): check increasing rowCount as add items * Fixed logic in placement of items in legend with multiple columns * Actual row count here should be 2, not 3 Co-authored-by: Ogi Moore --- examples/Legend.py | 2 +- pyqtgraph/graphicsItems/LegendItem.py | 38 ++++++++++++------- .../graphicsItems/tests/test_LegendItem.py | 10 +++-- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/examples/Legend.py b/examples/Legend.py index 5df9fb83..f3683cd0 100644 --- a/examples/Legend.py +++ b/examples/Legend.py @@ -13,7 +13,7 @@ win = pg.plot() win.setWindowTitle('pyqtgraph example: BarGraphItem') # # option1: only for .plot(), following c1,c2 for example----------------------- -# win.addLegend(frame=False, rowCount=1, colCount=2) +# win.addLegend(frame=False, colCount=2) # bar graph x = np.arange(10) diff --git a/pyqtgraph/graphicsItems/LegendItem.py b/pyqtgraph/graphicsItems/LegendItem.py index f5c5a559..bf01f03a 100644 --- a/pyqtgraph/graphicsItems/LegendItem.py +++ b/pyqtgraph/graphicsItems/LegendItem.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import math + from .GraphicsWidget import GraphicsWidget from .LabelItem import LabelItem from ..Qt import QtGui, QtCore @@ -30,8 +32,7 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): def __init__(self, size=None, offset=None, horSpacing=25, verSpacing=0, pen=None, brush=None, labelTextColor=None, frame=True, - labelTextSize='9pt', rowCount=1, colCount=1, - sampleType=None, **kwargs): + labelTextSize='9pt', colCount=1, sampleType=None, **kwargs): """ ============== =============================================================== **Arguments:** @@ -54,6 +55,10 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): accepted by :func:`mkPen ` is allowed. labelTextSize Size to use when drawing legend text. Accepts CSS style string arguments, e.g. '9pt'. + colCount Specifies the integer number of columns that the legend should + be divided into. The number of rows will be calculated + based on this argument. This is useful for plots with many + curves displayed simultaneously. Default: 1 column. sampleType Customizes the item sample class of the `LegendItem`. ============== =============================================================== @@ -71,8 +76,7 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): self.offset = offset self.frame = frame self.columnCount = colCount - self.rowCount = rowCount - self.curRow = 0 + self.rowCount = 1 if size is not None: self.setGeometry(QtCore.QRectF(0, 0, self.size[0], self.size[1])) @@ -231,29 +235,37 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): # FIND RIGHT COLUMN if not self.layout.itemAt(row, col): break - if col + 2 == nCol: - # MAKE NEW ROW - col = 0 - row += 1 + else: + if col + 2 == nCol: + # MAKE NEW ROW + col = 0 + row += 1 self.layout.addItem(sample, row, col) self.layout.addItem(label, row, col + 1) + # Keep rowCount in sync with the number of rows if items are added + self.rowCount = max(self.rowCount, row + 1) + print(f"_addItemToLayout set self.rowCount = {self.rowCount} \t row = {row} \t col = {col}") def setColumnCount(self, columnCount): """change the orientation of all items of the legend """ if columnCount != self.columnCount: self.columnCount = columnCount - self.rowCount = int(len(self.items) / columnCount) + + self.rowCount = math.ceil(len(self.items) / columnCount) + print(f"setColumnCount set self.rowCount = {self.rowCount}") for i in range(self.layout.count() - 1, -1, -1): self.layout.removeAt(i) # clear layout for sample, label in self.items: self._addItemToLayout(sample, label) self.updateSize() + print(f"end result is self.rowCount = {self.rowCount}") + print("\n") def getLabel(self, plotItem): """Return the labelItem inside the legend for a given plotItem - The label-text can be changed via labenItem.setText + The label-text can be changed via labelItem.setText """ out = [(it, lab) for it, lab in self.items if it.item == plotItem] try: @@ -297,13 +309,13 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): width = 0 for row in range(self.layout.rowCount()): row_height = 0 - col_witdh = 0 + col_width = 0 for col in range(self.layout.columnCount()): item = self.layout.itemAt(row, col) if item: - col_witdh += item.width() + 3 + col_width += item.width() + 3 row_height = max(row_height, item.height()) - width = max(width, col_witdh) + width = max(width, col_width) height += row_height self.setGeometry(0, 0, width, height) return diff --git a/pyqtgraph/graphicsItems/tests/test_LegendItem.py b/pyqtgraph/graphicsItems/tests/test_LegendItem.py index 080651fc..f17649ea 100644 --- a/pyqtgraph/graphicsItems/tests/test_LegendItem.py +++ b/pyqtgraph/graphicsItems/tests/test_LegendItem.py @@ -13,7 +13,6 @@ def test_legend_item_basics(): assert legend.columnCount == 1 assert legend.rowCount == 1 - assert legend.curRow == 0 assert legend.labelTextColor() is None assert legend.labelTextSize() == '9pt' @@ -65,21 +64,24 @@ def test_legend_item_basics(): legend.addItem(scatter, name="Scatter") assert len(legend.items) == 2 assert legend.columnCount == 1 - assert legend.rowCount == 1 + assert legend.rowCount == 2 curve = pg.PlotDataItem(name="Curve") legend.addItem(curve, name="Curve") assert len(legend.items) == 3 + assert legend.rowCount == 3 scrabble = pg.PlotDataItem(name="Scrabble") legend.addItem(scrabble, name="Scrabble") assert len(legend.items) == 4 assert legend.layout.rowCount() == 4 + assert legend.rowCount == 4 legend.setColumnCount(2) + assert legend.columnCount == 2 assert legend.rowCount == 2 - assert legend.layout.rowCount() == 3 + assert legend.layout.rowCount() == 2 # Remove items # ---------------------------------------------------- @@ -91,7 +93,7 @@ def test_legend_item_basics(): assert len(legend.items) == 3 legend.removeItem(curve) - assert legend.rowCount == 2 + assert legend.rowCount == 2 # rowCount will never decrease when removing assert legend.layout.rowCount() == 1 assert curve not in legend.items assert len(legend.items) == 2