Tags: graphistry/pygraphistry
Tags
feat(layout): built-in treemap layout, remove external dep, vectorize… … transforms (#1059) * feat(layout): replace external treemap layout dep with built-in vectorized implementation - Add graphistry/layout/gib/_squarify.py: pure Python + numpy squarified treemap layout algorithm (normalize_sizes + squarify + internal helpers) - Wire treemap.py to use the built-in implementation - Remove third-party dep from setup.py and mypy.ini - Add graphistry/tests/layout/test_treemap.py: 356 unit tests covering normalize_sizes, squarify geometry invariants, strip-loop boundary conditions, float-accumulation stress, numpy array inputs, and treemap() end-to-end integration; cross-validated against reference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * perf(layout): remove numpy dep from treemap layout; use built-in sum() np.sum() has ~3µs per-call overhead on small lists vs Python's sum() at ~100ns. Switching to sum() restores performance parity with the removed external dep (1.00-1.03x across n=2-500 partitions, verified on local + dgx-spark). Also removes the now-unnecessary numpy import from _squarify.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * perf(treemap): vectorize coordinate transforms + add layout benchmark Replace four per-row dict .map() lookups in partitioned_layout.py with two vectorized DataFrame merges (normalize + global positioning), giving O(nodes) work in a single join instead of 4× serial Python dict scans. Also fix treemap.py to compute partition_ids once outside the comprehension (was calling reset_index() inside the loop). Add benchmarks/layout/treemap.py with pre-resident data design: - DataFrame built once before timing loop (measures only treemap() call) - CPU=pandas in memory, GPU=cuDF on device (when available) - Algorithm-only sweep (ref vs built-in) + E2E sweep (cpu vs gpu) - RESULTS.md written alongside script Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * perf(treemap): update RESULTS.md with GPU benchmark from dgx-spark E2E numbers with pre-resident data (pandas in-memory vs cuDF on-device): - CPU baseline: ~250µs (3× faster than pre-vectorization ~800µs) - GPU crossover: ~50k total nodes; at 500k nodes GPU is 1.30× faster - Algorithm-only: 1.00–1.02× parity with reference across n=2–500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(treemap): use engine-native DataFrame for offsets; gitignore RESULTS.md - partitioned_layout.py: replace pd.DataFrame(partition_offsets) with df_cons(engine)(partition_offsets) so the offsets table is cuDF-native on the GPU path, not a pandas frame merged into a cuDF DataFrame - benchmarks/layout/.gitignore: exclude RESULTS.md (machine-specific output) - git rm benchmarks/layout/RESULTS.md (not source, belongs in .gitignore) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(release): promote Development to 0.54.0 in CHANGELOG Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(treemap): avoid suffix collision in global-transform merge Rename offsets columns to ox/oy/odx/ody before merging so columns that only exist on the right side (dx, dy) don't silently drop their suffix. Previously dx/dy came through unsuffixed (no collision) while x/y got _local/_offset suffixes, causing KeyError: 'dx_offset' at runtime. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
PreviousNext