GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |
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
|
Codecov Report❌ Patch coverage is 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:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
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).
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.
…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.
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.
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.
The pre-3.3 networkx stand-in raises only if draw() passes connectionstyle to it, which is the regression the test guards against.
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.
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.
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.
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.
_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.
…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.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.