Skip to content

PColorMeshItem: implement dataBounds and pixelPadding#2586

Merged
j9ac9k merged 3 commits intopyqtgraph:masterfrom
pijyoi:pcmi-databounds
Jan 21, 2023
Merged

PColorMeshItem: implement dataBounds and pixelPadding#2586
j9ac9k merged 3 commits intopyqtgraph:masterfrom
pijyoi:pcmi-databounds

Conversation

@pijyoi
Copy link
Copy Markdown
Contributor

@pijyoi pijyoi commented Jan 14, 2023

using QPicture.boundingRect() to compute boundingRect() has issues, which includes rounding the values to the next integral value.

Other issue fixed: width() and height() methods assume that the minimum coord is 0

Script that demonstrates the issues fixed by this PR.

  • Coords are chosen to be small and the bounding box will be over-sized on master.
  • print out of width() and height() are not correct on master.
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
import numpy as np

class ObjectBounds(QtWidgets.QGraphicsItem):
    def paint(self, painter, *args):
        pen = QtGui.QPen(QtCore.Qt.GlobalColor.red, 0, QtCore.Qt.PenStyle.DashLine)
        rect = self.boundingRect()
        painter.setPen(pen)
        painter.drawRect(rect)
        # print(rect)

    def boundingRect(self):
        return self.parentItem().boundingRect()

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()

rng = np.random.default_rng()
shape = (100, 100)
az = np.linspace(np.pi/6, np.pi*5/6, shape[0]+1)
rg = np.linspace(0.25, 1.25, shape[1]+1)
X = rg[:, np.newaxis] * np.cos(az)
Y = rg[:, np.newaxis] * np.sin(az)
Z = rng.uniform(size=shape)

pcmi = pg.PColorMeshItem(X, Y, Z)
pw.addItem(pcmi)
rect = ObjectBounds(pcmi)

print(pcmi.width(), pcmi.height())

pg.exec()

@pijyoi pijyoi force-pushed the pcmi-databounds branch 2 times, most recently from fc3575e to 58c5e19 Compare January 15, 2023 06:18
@pijyoi
Copy link
Copy Markdown
Contributor Author

pijyoi commented Jan 15, 2023

Looking at the very first commit of the PR #1273 for PColorMeshItem, the original implementations of width(), height() and boundingRect() were modeled on the implementation for ImageItem, which draws the image at the origin. For ImageItem, the user applies scale and translation transformations to "move" it to the correct spot.

As PColorMeshItem can be drawn with arbitrary coordinates, this model is not appropriate.
A couple of questions:

  1. Are width() and height() methods even necessary?
  2. And if yes, why return None instead of just zero? (ImageItem returns None, but is there a need to copy ImageItem's interface?)
    def width(self):
        if self.x is None:
            return None
        return len(self.x)

    def height(self):
        if self.y is None:
            return None
        return len(self.y)

    def boundingRect(self):

        if self.z is None:
            return QtCore.QRectF(0., 0., 0., 0.)
        return QtCore.QRectF(0., 0., float(self.width()), float(self.height()))

@pijyoi pijyoi marked this pull request as ready for review January 19, 2023 13:17
@pijyoi
Copy link
Copy Markdown
Contributor Author

pijyoi commented Jan 20, 2023

Would it make sense to force/require the edgecolor pen to be cosmetic? It would simplify the dataBounds method.
It doesn't seem to make sense to draw the polygon edges with a non-cosmetic pen.

@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Jan 20, 2023

Hi @pijyoi sorry for the late response.

I don't think the width and height methods are necessary. I can see the case where having thick lines for the edge-colors would be desired; but I'm not sure it's worth it to support that functionality at the expense of complexity. I would be good with supporting only cosmetic pens. Should add a note about that in the docstring, and maybe put a comment in the code referencing a post here about not supporting non-cosmetic pens.

@pijyoi
Copy link
Copy Markdown
Contributor Author

pijyoi commented Jan 20, 2023

I can see the case where having thick lines for the edge-colors would be desired; but I'm not sure it's worth it to support that functionality at the expense of complexity. I would be good with supporting only cosmetic pens.

It's okay to support thick cosmetic pens. That code is within pixelPadding. Whether the pen is thick or not, half the pen width still needs to be accounted for.

The code that supports non-cosmetic pens is within dataBounds, and is the code that I would like to remove.

@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Jan 20, 2023

The code that supports non-cosmetic pens is within dataBounds, and is the code that I would like to remove.

I'm good with that.

@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Jan 21, 2023

Thanks @pijyoi for patching up PColorMeshItem! Changes LGTM, merging!

@j9ac9k j9ac9k merged commit 3ab66ab into pyqtgraph:master Jan 21, 2023
@pijyoi pijyoi deleted the pcmi-databounds branch January 21, 2023 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants