GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix viz bugs and bring graphblas/viz.py under test and coverage by eriknw · Pull Request #597 · python-graphblas/python-graphblas

Conversation

@eriknw

@eriknw eriknw commented Aug 4, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

graphblas/viz.py had zero tests and was omitted from coverage. This branch
adds smoke tests, fixes the bugs the tests uncovered plus two reported in the
pyOpenSci review, and un-omits the module.

  • Add smoke tests (a928875): nine Agg-backend tests covering spy, draw,
    and datashade, with importorskip guards so minimal environments see clean
    skips.

  • Fix NameError in viz.spy (2d11071): spy(A, figure=fig) and
    spy(A, axes=ax) both crashed because the fig local was only bound when
    spy created the figure itself. Regression tests cover both forms.

  • Fix datashade cell positioning ([pyos][visualization] viz.datashade() wrong positioning of matrix elements #473) and reciprocal edges in draw
    ([pyos][visualization] Reciprocal directed edges overlap #474)
    (c2ba762): datashade rendered each element half a cell off
    from the tick, disagreeing with spy; it now uses the imshow
    integer-center convention. Reciprocal directed edges drew as coincident
    lines with one weight label hidden; they now draw as arcs with separated
    labels. The arc rendering needs networkx 3.3, so draw() feature-detects
    the connectionstyle parameter and keeps the straight rendering on older
    networkx.

  • Measure coverage (9e27167): removes the coverage omit block (viz.py
    was its only entry); 87.6% covered counting statements and branches.

  • Install the datashade stack in the notebooks CI jobs (d02a7f2): the
    datashade tests skip unless datashader, holoviews, hvplot and bokeh are
    installed, and no CI job installed them, so viz.datashade never ran in CI.
    The notebooks jobs, which already add matplotlib for the rest of viz, add
    these four where Numba is installed (datashader needs it). Every distinct
    notebooks draw (673 combinations of Python 3.11-3.15 with its numpy, pandas
    and numba pins) solves with them on linux-64, osx-arm64 and win-64, and
    test_viz.py passes with them on the newest and the oldest of those draws.

  • Exclude a failure-only line of a test from coverage (d71e93e): the
    test's stand-in for networkx before 3.3 raises only if draw() passes it
    connectionstyle, which is the regression the test guards against.

  • Refuse what viz cannot plot. These are review follow-ups; the gaps predate this PR.

    • Datashade a boolean Matrix as 0 and 1: a BOOL Matrix used to plot blank, with holoviews
      only logging "input must be numeric".
    • Raise from viz.datashade for a Matrix it cannot plot: a complex or UDT Matrix raises
      TypeError, and a Matrix with no rows or columns raises ValueError, when datashade is called.
      Before, the lazy render logged a warning beside a blank plot.
    • Raise a clear TypeError from viz.draw for a complex or UDT Matrix: before, the error came
      from deep inside networkx's layout.
    • Refuse a non-square Matrix in viz.draw, as its docstring says: a behavior change. A
      rectangular Matrix used to draw a graph of its rows plus whichever columns had entries. If
      you would rather draw rectangular matrices (as a bipartite graph, say), say so; otherwise it
      refuses.
    • Drop the unreachable float64 index fallback from viz datashade: GraphBLAS dimensions stop
      at 2**60, so those branches could not run.

Stack created with GitHub Stacks CLI • Give Feedback 💬

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@eriknw eriknw changed the title 17 viz fixes Fix viz bugs and bring graphblas/viz.py under test and coverage Aug 4, 2026
@eriknw
eriknw marked this pull request as ready for review August 4, 2026 16:07
@eriknw
eriknw force-pushed the 17-viz-fixes branch 2 times, most recently from 491bbf3 to cf2817d Compare August 5, 2026 00:06
@eriknw
eriknw force-pushed the 17-viz-fixes branch from cf2817d to c963343 Compare August 5, 2026 03:18
@eriknw
eriknw force-pushed the 17-viz-fixes branch from c963343 to f9694b6 Compare August 5, 2026 17:44
@eriknw
eriknw force-pushed the 17-viz-fixes branch from f9694b6 to f354b89 Compare August 5, 2026 18:03
@eriknw
eriknw force-pushed the 17-viz-fixes branch from f354b89 to e619c3d Compare August 5, 2026 18:05
@eriknw
eriknw force-pushed the 17-viz-fixes branch from e619c3d to 7ac3854 Compare August 6, 2026 07:59
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 7ac3854 to 40ed8c3 Compare August 6, 2026 15:39
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 40ed8c3 to f5ec848 Compare August 6, 2026 15:41
@eriknw
eriknw force-pushed the 17-viz-fixes branch from f5ec848 to 2f24476 Compare August 6, 2026 20:36
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 2f24476 to 906f542 Compare August 6, 2026 20:42
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 906f542 to 31034b9 Compare August 7, 2026 02:48
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 31034b9 to 8c3f97f Compare August 7, 2026 05:09
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 8c3f97f to 536bdbc Compare August 26, 2026 17:30
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 536bdbc to fbe6d5f Compare September 18, 2026 03:09
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 926d31d to 0615cdd Compare October 1, 2026 17:11
@eriknw
eriknw force-pushed the 17-viz-fixes branch 3 times, most recently from 84a47e5 to a9709ed Compare October 3, 2026 04:57
@eriknw
eriknw force-pushed the 17-viz-fixes branch from a9709ed to 9709e12 Compare October 4, 2026 06:21
@eriknw
eriknw removed this pull request from stack #634 October 8, 2026 21:02
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 9709e12 to 1e206ca Compare October 8, 2026 21:40
@eriknw
eriknw added this pull request to stack #635 October 8, 2026 21:46
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 1e206ca to 668d7ee Compare October 9, 2026 03:06
@eriknw
eriknw force-pushed the 17-viz-fixes branch from 668d7ee to 8a5754a Compare October 9, 2026 05:25
@codecov

codecov Bot commented Oct 19, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.95833% with 2 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (39b-from-coo-broadcast-iso@c8ee855). Learn more about missing BASE report.

Additional details and impacted files
@@                      Coverage Diff                      @@
##             39b-from-coo-broadcast-iso     #597   +/-   ##
=============================================================
  Coverage                              ?   98.78%           
=============================================================
  Files                                 ?      109           
  Lines                                 ?    34838           
  Branches                              ?     3997           
=============================================================
  Hits                                  ?    34416           
  Misses                                ?      271           
  Partials                              ?      151           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

eriknw added 13 commits November 12, 2026 11:25
@eriknw
Add smoke tests for graphblas.viz
731fc1b
viz.py previously had zero tests. Nine Agg-backend smoke tests cover
spy (default, centered, explicit axes), draw (renders nodes/labels,
rejects non-Matrix), and datashade (single, list, grid, empty agg).
Every optional dependency is guarded with importorskip so a
minimal-environment run sees clean skips: without matplotlib the whole
module skips; without datashader the four datashade tests skip and the
rest run (both verified by simulation).
@eriknw
Fix NameError in viz.spy with an explicit figure or axes
7ec05b7
spy() bound the ``fig`` local only when it created the figure itself, so
``spy(A, figure=fig)`` crashed creating the axes and ``spy(A, axes=ax)``
crashed in the auto-markersize path (found while writing the smoke
tests). The figure kwarg is now used when given, and auto-markersize
reads dpi from ``axes.figure``, which is correct in all three call
forms. Regression tests cover both previously-crashing forms.
@eriknw
Fix viz.datashade cell positioning and separate reciprocal edges in v…
b5749c3
…iz.draw

Two bugs reported in the pyOpenSci review.  Both change viz.py, so they
are itemized in a single commit.

gh-473: datashade binned element (r, c) into the pixel spanning
[c, c+1) x [r, r+1), so it rendered centered at (c+0.5, r+0.5), half a
cell off the tick labeled (c, r); spy centers the same element exactly
on the tick.  The axis limits now use the imshow integer-center
convention (-0.5 to n-0.5), making datashade agree with spy.  The
issue's other symptom (elements invisible until zoom-out) does not
reproduce on the current holoviews/hvplot/bokeh stack; it was a
2023-era library artifact.

gh-474: reciprocal directed edges drew as coincident straight lines
with both weight labels on the same midpoint, hiding one weight.
Reciprocal pairs now draw with an arc (connectionstyle arc3, rad 0.1)
and matching label placement, so both arrows and both weights are
visible; other edges and self-loops stay straight.

The gh-474 fix needs networkx 3.3, the release that gave
draw_networkx_edge_labels its connectionstyle parameter.  We support
networkx >=2.8, so draw() feature-detects that parameter and keeps the
previous straight rendering when it is missing; passing it to an older
networkx raises TypeError.  Curving the edges but not the labels would
be worse than not curving at all, since the labels would sit back on the
shared chord midpoint (the overlap gh-474 is about) and would no longer
track their arrows.

Both fixes carry display-free regression tests: datashade pixel centers
match spy's convention, and draw places the two weight labels at
separated anchors.  The label check measures separation as a fraction of
the edge length rather than comparing positions for exact inequality,
because networkx returns two midpoint anchors that differ by
floating-point noise even when the labels coincide on screen.  A third
test stands in a pre-3.3 signature to cover the fallback.
@eriknw
Measure coverage of graphblas/viz.py
dd222db
Removes the coverage omit block (viz.py was its only entry, with a TODO
to un-omit once tests existed; they do now).  The viz test module covers
87.6% of viz.py counting statements and branches, 91.1% counting
statements alone.  The misses are the optional-import failure path, the
interactive plt.show() path, and guards for inputs the tests do not
construct: matrices too large for int64 indices, ragged aggregator
grids, and caller-supplied opts_kwargs.
@eriknw
Make viz tests skip cleanly on old networkx and broken matplotlib
2baf612
@eriknw
Install the datashade stack in the notebooks CI jobs
f4942c7
graphblas/tests/test_viz.py's datashade tests skip unless datashader,
holoviews, hvplot and bokeh are installed, and no CI job installed them,
so they never ran and viz.datashade never counted for coverage. The
notebooks jobs already add matplotlib for the rest of viz, so add these
four there too.

datashader depends on numba, so they are installed only where numba is.
The notebooks jobs never skip numba at random; this keeps a pypy draw, or
a draw the version picker leaves without a compatible numba, solvable.

Every distinct notebooks draw the picker makes (673 combinations of
Python 3.11-3.15 with its numpy, pandas and numba pins, from 20000 draws
per Python) solves with the four added on linux-64, osx-arm64 and win-64,
picking the newest datashader (0.19.1), holoviews (1.23.2) and hvplot
(0.12.2) every time. test_viz.py passes with them on the newest stack
(Python 3.13, numpy 2.5, pandas 3.1, numba 0.68) and on the oldest draw
(Python 3.11, numpy 1.24, pandas 1.5, numba 0.57).

scripts/check_versions.sh lists them with the other dependencies CI
tests.
@eriknw
Exclude a test stand-in's failure-only raise from coverage
fff2e19
The pre-3.3 networkx stand-in raises only if draw() passes connectionstyle
to it, which is the regression the test guards against.
@eriknw
Datashade a boolean Matrix as 0 and 1
eddd998
viz.datashade on a BOOL Matrix returned its plot, which then came out
blank: datashader aggregates only numbers, and holoviews logged "input
must be numeric" from the lazy render instead of raising it. Hand
datashader the values as uint8, so a boolean Matrix plots with any
aggregator; "sum", for example, counts the true values in each pixel.
@eriknw
Raise from viz.datashade for a Matrix it cannot plot
4433ad8
datashade returns a lazy holoviews plot. For a complex or UDT Matrix, or
one with no rows or no columns, the error came only when it rendered
(a numba TypingError, "NumPy datatype ... not supported", or
ZeroDivisionError), and holoviews logged it as a warning and showed a
blank plot. Check the dtype and shape when datashade is called instead:
TypeError for complex and UDT values, ValueError for a zero dimension.
An empty Matrix with rows and columns still plots.
@eriknw
Raise a clear TypeError from viz.draw for a complex or UDT Matrix
5079231
draw lays the graph out with the Matrix values as edge weights, and
networkx reads those as floats. A complex Matrix failed deep inside
networkx with "float() argument must be a string or a real number, not
'complex'", and a UDT one with "shape mismatch: value array of shape
(2,2) could not be broadcast". Refuse both before building the graph.
A boolean Matrix still draws, its weights read as 0 and 1.
@eriknw
Refuse a non-square Matrix in viz.draw, as its docstring says
17357e9
draw's docstring asks for a square adjacency Matrix, but a rectangular
one drew without complaint: to_networkx makes a node of each row and of
each column with an entry, so a 2x5 Matrix with entries in columns 0 and
4 drew nodes 0, 1 and 4 and left out 2 and 3. Raise ValueError instead.
@eriknw
Drop the unreachable float64 index fallback from viz datashade
a7f459b
_matrix_to_dataframe cast the uint64 indices to float64 when a dimension
and an index exceeded the int64 max, and to int64 otherwise. GraphBLAS
dimensions stop at 2**60 (GrB_INDEX_MAX + 1; a larger nrows raises
InvalidValue, checked on SuiteSparse 8.2 and 10.5), so the float64 branches
could never run, and their rows.max() would have raised on a Matrix with
no entries. Always cast to int64.
@eriknw
Skip the UDT draw test where vanilla cannot build a UDT Matrix withou…
8a1bd7f
…t Numba

test_draw_rejects_udt builds its Matrix with from_coo, whose build needs
binary.any on the UDT. The suitesparse-vanilla backend has that only through
Numba (main too), so without Numba the test failed in its setup with
'any does not work with ...', before viz.draw was called.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@eriknw
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.