Skip to content

Fix draw_networkx_nodes with list node_shape and add regression test #8363

Merged
dschult merged 3 commits intonetworkx:mainfrom
NaorTm:fix-node-shape-list
Dec 7, 2025
Merged

Fix draw_networkx_nodes with list node_shape and add regression test #8363
dschult merged 3 commits intonetworkx:mainfrom
NaorTm:fix-node-shape-list

Conversation

@NaorTm
Copy link
Copy Markdown
Contributor

@NaorTm NaorTm commented Dec 4, 2025

Fixed #8350
This pull request fixes the behavior of draw_networkx_nodes when node_shape
is passed as a Python list.

Motivation

Previously, draw_networkx_nodes correctly handled

  • a scalar node_shape value such as "o",
  • and a numpy.ndarray of shapes,

but when node_shape was a plain Python list, the comparison

node_shape == shape

dschult
dschult previously approved these changes Dec 4, 2025
Copy link
Copy Markdown
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Straightforward improvement. Thanks for the test too!

@dschult
Copy link
Copy Markdown
Member

dschult commented Dec 4, 2025

Looks like there are whitespace changes requested (you can do them manually or use pre-commit which is described in the contributor guide.

The test base failures are not related to this PR. Its a cpython error that is being worked on.

@NaorTm NaorTm force-pushed the fix-node-shape-list branch from 0f05ba4 to c54fc88 Compare December 4, 2025 00:29
Comment on lines +1172 to +1173
node_color="red", # scalar color (supported)
node_shape=shapes, # list of shapes – this used to be buggy
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is quite right - this is already allowed and will pass on main. The unit test should fail on main and pass with the fix. The easiest way to do this is to adhere more closely to the example in the OP of the issue, which uses colors=["red"]*5 (i.e. a list of scalars).

Copy link
Copy Markdown
Member

@dschult dschult Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops... missed that!
Yes -- this test should be using a list for each of node_color and node_shape.
Good catch!

[Removed some mixed up comments...]
We do need to change this test. Sorry for the confusion.

@dschult dschult dismissed their stale review December 5, 2025 12:25

The problem we are solving here appears from the original post in that issue, not from my apparently incorrect summary further down.

Copy link
Copy Markdown
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK... This PR does fix a problem with the current code.
When node_shapes is a list, no exception is raised. But the resulting collection is empty. No nodes satisfy the condition node_shape == shape so nothing is added to the collection.

We need to update the test to check that nodes actually has (some number of) elements in it.
See the suggestions below.

We should also remove the subplots and fig/ax stuff. No ax=ax is needed on the function call.

)

# Should get a valid PathCollection back (same behavior as with numpy arrays)
assert isinstance(nodes, mpl.collections.PathCollection)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we need here is to check that the "length of the PathCollection" is >0. So I think the following assert is needed.

Suggested change
assert isinstance(nodes, mpl.collections.PathCollection)
assert len(nodes.get_offsets()) > 0

Note that we do have to assert on this length here. Even if the len is not 5 it should be > 0. So the comment following this can be removed.

And the subplots and ax=ax stuff can be removed too. We only need to call the function.

@rossbar
Copy link
Copy Markdown
Contributor

rossbar commented Dec 5, 2025

We should also remove the subplots and fig/ax stuff. No ax=ax is needed on the function call.

Unfortunately this stuff is necessary, but for a very indirect reason... if we don't include explicit fig/ax creation in the tests, then it is done implicitly inside the draw_networkx_* call. For user code this is no problem, but for the test suite it means that plt.gca and plt.gcf get populated, which breaks the scope of the unit test. These types of things often result in errors in the pytest-randomly runs, which catch inter-test dependencies when they're shuffled.

Of course, this detail isn't documented anywhere!

@dschult
Copy link
Copy Markdown
Member

dschult commented Dec 6, 2025

Ahh -- interesting point about ax and fig creation needing to be explicit so we are sure to test only the parts of draw_networkx_nodes that we want to test.

So, now we just need to change the assert and update/remove the comment after it.

@dschult
Copy link
Copy Markdown
Member

dschult commented Dec 6, 2025

In the sense that this is a bug-fix. It might be good to include it in 3.6.1 too.
I'll put the milestone up and @MridulS can choose which way to handle it. It's certainly not critical.

@dschult dschult added this to the 3.6.1 milestone Dec 6, 2025
@dschult
Copy link
Copy Markdown
Member

dschult commented Dec 7, 2025

I went ahead and pushed the suggested change (test now fails on main) and tweaked the comments.
Hoping to get this in before a minor/bug-fix release of 3.6.1 today. 🚀

@dschult dschult merged commit 696edb6 into networkx:main Dec 7, 2025
52 checks passed
@dschult dschult modified the milestones: 3.6.1, 3.6 Dec 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

networkx_draw_nodes fails when both node_color and node_shape are lists

4 participants