Repository navigation
go-plot v0: matplotlib-model plotting in pure Go, tested against matplotlib - #1
Merged
Merged
Conversation
…FormatterSciNotation Ported from matplotlib 3.11.2 with Python/NumPy float semantics (floor division, correctly rounded powers of ten, no fused multiply-add), and checked against 408 cases generated from real matplotlib axes: locations bit for bit, labels and offset text character for character. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…b's exact tables The lookup tables and named colours are generated from matplotlib 3.11.2 by tools/gen_colormaps.py; the test checks 1008 samples of every map (floats and bytes) against an independent fixture from the same matplotlib. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Figure/Subplots/AddAxes with matplotlib's GridSpec placement; Axes with Plot, Scatter, Bar/Barh, Hist, FillBetween, ErrorBar, Imshow, Contour, Contourf, Axhline/Axvline, Text/Annotate, Legend (with 'best' placement), titles and labels, grid, limits, linear and log scales, TwinX; Colorbar. render/ draws through go-widgets/painter (masks and images) with go-gfx vector coverage for strokes and fills, or to SVG; text/ sets DejaVu Sans via go-opentype and TeX math via go-tex/math. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al comparison main.go and figures.py draw the same eleven figures; compare.py finds the axes frames, the tick marks and the C0 pixels in both renderings with one detector and checks them against stated tolerances. Two perturbed figures are negative controls the comparison must fail. Also: superscripts in tick labels use the x-height of the x glyph, and one-colour contour lines dash negative levels, as matplotlib does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arness A 1e6-point line to PNG goes from 121 ms to 52 ms: data limits are taken once per artist, long strokes are rasterised in 512-segment pieces (the coverage sweep sorts crossings by insertion, quadratic in a dense line), and STIX Two Math is parsed only when a label needs TeX. tools/compare/perf.py times go-plot against matplotlib interleaved, fresh processes, medians; tools/gen_layout.py records matplotlib's layout of small figures for the tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tplotlib's 30 figures (15 kinds x 2 sizes) from tools/gen_layout.py; LICENSE copyright line now names the go-plot/plot authors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erything tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… contour tools/gen_ticker_units.py records matplotlib's MaxNLocator, LogLocator, ScalarFormatter, LogFormatterSciNotation, nonsingular and %g called with non-default parameters; the port matches every one (base-e log ticks to 1e-15, the rest bit for bit). LogLocator gains subs="all". Zero-area band polygons are dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logNonsingular widened a single value to the decades two apart; matplotlib takes the decade strictly below and above (3 -> [1, 10], 10 -> [1, 100]). Dead branches the tests showed unreachable are removed with a note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Running the test binaries on s390x (qemu, locally) caught a platform difference: LogFormatterSciNotation's coefficient b**(fx - exponent) sits within an ulp of 1.5 for x = 6, b = 2 and rounds either way depending on pow; x / b**exponent is exact and gives matplotlib's answer everywhere. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rom code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TightLayout ports _auto_adjust_subplotpars and is checked against matplotlib's positions after fig.tight_layout() for 12 figures (every edge within 0.005 of the figure, worst 0.0049). Text boxes now start at the pen and are as wide as the string's advance, as FreeType's box is in matplotlib within a pixel or two; this halves the mean pixel difference of every reference figure (line: 2.10 -> 1.01). docs/design.md records the notebook census (339 notebooks) the API's shape follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
First version of go-plot: a pure-Go (CGO=0) plotting library with matplotlib's object model and defaults, SVG and PNG output, and TeX labels typeset by go-tex/math.
What is in it
plot:Figure,Subplots,AddAxes,TightLayout;Plot,Scatter,Bar/Barh,Hist,FillBetween,ErrorBar,Imshow(+Colorbar),Contour/Contourf,Axhline/Axvline,Text/Annotate,Legend, titles, labels, grid, limits, linear/log scales,TwinX;SaveSVG,SavePNG,Display()(image/svg+xml,image/png). Data: numeric slices or*ndarray.Arrayof any dtype.ticker: AutoLocator/MaxNLocator, ScalarFormatter (offset, scientific), LogLocator, LogFormatterSciNotation.colors: named colours, tab10 cycle, viridis/plasma/inferno/magma/cividis/gray/coolwarm/RdBu with matplotlib's LUTs (generated bytools/gen_colormaps.py).contour(marching squares),render(raster via go-widgets/painter + go-gfx coverage; vector SVG),text(DejaVu Sans via go-opentype; TeX via go-tex/math).Verification
TightLayout: 12 figures within 0.005 of the figure (worst 0.0049 = 2.4 px; text widths are measured from advances, matplotlib's from FreeType's hinted box).tools/compare): in 12 of 14 every axes frame and tick mark is on the same pixel, curve overlap 0.994–1.000. Two fail the 1-px tolerance and are reported, not loosened: theTightLayoutfigure (2 px, text-width measurement) and the 1e6-point line (22% fewer saturated pixels: anti-aliasing of a self-overlapping stroke). Negative controlsline_shifted(4 px) andline_1px(2 px tick error) both fail as required.-race; test binaries also run locally under qemu on s390x, ppc64le, riscv64 and on 386 (this caught one platform-dependent label, fixed).Performance (medians, interleaved, loaded host — docs/perf.md)
The API follows a census of 339 notebooks (subplots, plot, set_xlabel/ylabel/title, legend, figure, tight_layout, set_ylim, axhline all present;
pyplot.showisDisplay); differences from matplotlib and what v0 leaves out are listed indocs/design.md.CI: gofmt, vet, build, the 100% coverage gate on Linux/macOS/Windows, native amd64/arm64, qemu riscv64/loong64/ppc64le/s390x, cross-builds for 386, arm, js/wasm, wasip1/wasm, govulncheck.
mainwas created by GitHub (initial LICENSE + README); this PR is the first code. Not to be merged by its author.🤖 Generated with Claude Code