Skip to content

TypeError when using multiple pens for different lines#2704

Merged
j9ac9k merged 2 commits intopyqtgraph:masterfrom
adriandavidauer:patch-1
May 11, 2023
Merged

TypeError when using multiple pens for different lines#2704
j9ac9k merged 2 commits intopyqtgraph:masterfrom
adriandavidauer:patch-1

Conversation

@adriandavidauer
Copy link
Copy Markdown
Contributor

lastPen = None
for i in range(pts.shape[0]):
    pen = self.pen[i]
    if np.any(pen != lastPen):

comparison with None will always cause

if np.any(pen != lastPen):
TypeError: Cannot compare structured or void to non-void arrays.

This does not really follow DRY principle but was the best solution I could come up with using static types in structured array

Detail the reasoning behind the code change. If there is an associated issue that this PR will resolve add

Fixes #

Other Tasks

Bump Dependency Versions

Files that need updates

Confirm the following files have been either updated or there has been a determination that no update is needed.

  • README.md
  • setup.py
  • tox.ini
  • .github/workflows/main.yml and associated requirements.txt and conda environemt.yml files
  • pyproject.toml
  • binder/requirements.txt
Pre-Release Checklist

Pre Release Checklist

  • Update version info in __init__.py
  • Update CHANGELOG primarily using contents from automated changelog generation in GitHub release page
  • Have git tag in the format of pyqtgraph-
Post-Release Checklist

Steps To Complete

  • Append .dev0 to __version__ in __init__.py
  • Announce on mail list
  • Announce on Twitter

comparison with None will always cause 
```
if np.any(pen != lastPen):
TypeError: Cannot compare structured or void to non-void arrays.
```
This does not really follow DRY principle but was the best solution I could come up with using static types in structured array
@pijyoi
Copy link
Copy Markdown
Contributor

pijyoi commented Apr 26, 2023

How about:

if lastPen is None or np.any(pen != lastPen):

@adriandavidauer
Copy link
Copy Markdown
Contributor Author

How about:

if lastPen is None or np.any(pen != lastPen):

This is obviously the more elegant solution 😅
Edited it.
@pijyoi Let me know if there is something else I need to do 😉

@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented May 11, 2023

This LGTM, thanks for the PR @adrianlubitz and thanks for the review/feedback @pijyoi

@j9ac9k j9ac9k merged commit ca15c87 into pyqtgraph:master May 11, 2023
@adriandavidauer
Copy link
Copy Markdown
Contributor Author

@j9ac9k When will this be uploaded to PyPI as a new Version? I want to use it as a dependency in CoBaIR and PyPI only allows dependencies from PyPI itself. Looking forward to Version 0.13.4 📦 🥳

@pijyoi
Copy link
Copy Markdown
Contributor

pijyoi commented Jun 5, 2023

Looking at the code, I don't think that passing in red,green,blue,alpha,width as a numpy record array to specify the pens seems a good idea. (It's also possible to pass in a regular numpy array to specify r,g,b,a, but that's not documented in the docstring)
The lastPen variable is a sort of optimization to avoid recreating QPens, but it only works if the same-colored pens are adjacent.

I would think a more useful input parameter would be a Python list of (either QPen or something that mkPen accepts). This way, the user can use the same pre-created QPen object within the list. (Similar to what BarGraphItem code is doing)

Prior to this PR, use of multiple pens wouldn't have worked anyway. Would it be a good opportunity to fix the api now?

@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Jun 5, 2023

Would it be a good opportunity to fix the api now?

Now is always better than later.

@pijyoi
Copy link
Copy Markdown
Contributor

pijyoi commented Jun 6, 2023

Prior to this PR, use of multiple pens wouldn't have worked anyway.

Now I am puzzled. https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/examples/GraphItem.py specifies multiple pens and does work on 0.13.3. So what was this PR fixing?

In [40]: lines = np.array([
    ...:     (255,0,0,255,1),
    ...:     (255,0,255,255,2),
    ...:     (255,0,255,255,3),
    ...:     (255,255,0,255,2),
    ...:     (255,0,0,255,1),
    ...:     (255,255,255,255,4),
    ...:     ], dtype=[('red',np.ubyte),('green',np.ubyte),('blue',np.ubyte),('alpha',np.ubyte),('width',float)])

In [41]: lines[4] == None
Out[41]: False

In [42]: lines[4] != None
Out[42]: True

In [43]: np.any(lines[4] != None)
Out[43]: True

@adriandavidauer
Copy link
Copy Markdown
Contributor Author

Prior to this PR, use of multiple pens wouldn't have worked anyway.

Now I am puzzled. https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/examples/GraphItem.py specifies multiple pens and does work on 0.13.3. So what was this PR fixing?

In [40]: lines = np.array([
    ...:     (255,0,0,255,1),
    ...:     (255,0,255,255,2),
    ...:     (255,0,255,255,3),
    ...:     (255,255,0,255,2),
    ...:     (255,0,0,255,1),
    ...:     (255,255,255,255,4),
    ...:     ], dtype=[('red',np.ubyte),('green',np.ubyte),('blue',np.ubyte),('alpha',np.ubyte),('width',float)])

In [41]: lines[4] == None
Out[41]: False

In [42]: lines[4] != None
Out[42]: True

In [43]: np.any(lines[4] != None)
Out[43]: True

Hi @pijyoi,
I haven't had much time lately but now I came to the point where I had some time to investigate.
My mistake was that I had my array nested one level to deep. It looked something like that:

lines = np.array([
    np.array([(255, 0, 0, 255, 1)], dtype=[
             ('red', np.ubyte), ('green', np.ubyte), ('blue', np.ubyte), ('alpha', np.ubyte), ('width', float)]),
    np.array([(255, 0, 255, 255, 2)], dtype=[
             ('red', np.ubyte), ('green', np.ubyte), ('blue', np.ubyte), ('alpha', np.ubyte), ('width', float)]),
    np.array([(255, 0, 255, 255, 3)], dtype=[
             ('red', np.ubyte), ('green', np.ubyte), ('blue', np.ubyte), ('alpha', np.ubyte), ('width', float)]),
    np.array([(255, 255, 0, 255, 2)], dtype=[
             ('red', np.ubyte), ('green', np.ubyte), ('blue', np.ubyte), ('alpha', np.ubyte), ('width', float)]),
    np.array([(255, 0, 0, 255, 1)], dtype=[
             ('red', np.ubyte), ('green', np.ubyte), ('blue', np.ubyte), ('alpha', np.ubyte), ('width', float)]),
    np.array([(255, 255, 255, 255, 4)], dtype=[
             ('red', np.ubyte), ('green', np.ubyte), ('blue', np.ubyte), ('alpha', np.ubyte), ('width', float)]),
])

With the solution from the the PR nested arrays work as well and additionally I could fix my issue and can use pyqtgraph 0.13.3 as dependency.

Thanks 😄

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.

3 participants