% pgflibrarypgfplots.autonode.code.tex -- autonomous PGFPlots label library. % Copyright (C) 2026 Christophe Jorssen. LPPL 1.3c or later. % Standalone library version 1.0.0, 2026-09-20. % % This file is intentionally written as generic TeX and follows PGFPlots' % library naming convention. Load it with \usepgfplotslibrary{autonode} from % LaTeX, plain TeX, or ConTeXt after the format's PGFPlots frontend is loaded. % The numerical placement algorithms live in pgfplots-autonode.lua. % % Public entry points: % - /pgfplots/auto node placement % - /pgfplots/auto node algorithm= % - /pgfplots/auto node debug= % - \pgfplotsautonode[]{} % % Design note: % \pgfplotsautonode is meant to be used as a pgfplots trailing path command. % Therefore its bracket argument is mandatory. This avoids the fragile % interaction between LaTeX optional-argument parsing and TikZ's path parser. \expandafter\ifx\csname pgfplotsautonode@loaded\endcsname\relax \else \expandafter\endinput \fi \expandafter\def\csname pgfplotsautonode@loaded\endcsname{1} \expandafter\ifx\csname directlua\endcsname\relax \errmessage{pgfplots-autonode requires LuaTeX} \fi \expandafter\edef\csname pgfplotsautonode@oldatcatcode\endcsname{\the\catcode`\@}% \catcode`\@=11\relax \newcount\pgfplotsautonode@id \newcount\pgfplotsautonode@debuglevel \newcount\pgfplotsautonode@maxiterations \newcount\pgfplotsautonode@exactmaxlabels \newcount\pgfplotsautonode@exactmaxstates \newcount\pgfplotsautonode@measureindex \newif\ifpgfplotsautonode@sloped \newif\ifpgfplotsautonode@allowupsidedown \newif\ifpgfplotsautonode@allowoutside \newif\ifpgfplotsautonode@showboundingboxes \newif\ifpgfplotsautonode@showcandidates \newif\ifpgfplotsautonode@showrejectedcandidates \newif\ifpgfplotsautonode@placementenabled \newif\ifpgfplotsautonode@missinghookwarned \pgfplotsautonode@debuglevel=0\relax \pgfplotsautonode@maxiterations=40\relax \pgfplotsautonode@exactmaxlabels=10\relax \pgfplotsautonode@exactmaxstates=50000\relax \def\pgfplotsautonode@defaultcandidates{51}% \def\pgfplotsautonode@defaultcandidatestrategy{around-preferred}% \def\pgfplotsautonode@algorithm{repair}% \def\pgfplotsautonode@bboxmode{axis-aligned}% \def\pgfplotsautonode@failuremode{warn}% \def\pgfplotsautonode@bordermargin{2pt}% \def\pgfplotsautonode@overlaptolerance{0.2pt}% \pgfplotsautonode@allowoutsidefalse \pgfplotsautonode@allowupsidedownfalse \pgfplotsautonode@showboundingboxesfalse \pgfplotsautonode@showcandidatesfalse \pgfplotsautonode@showrejectedcandidatesfalse \pgfplotsautonode@placementenabledfalse \pgfplotsautonode@missinghookwarnedfalse % Load the Lua companion file. ConTeXt protects direct access to the kpathsea % library and exposes its own resolver, while LaTeX and plain TeX expose kpse. % The final fallback helps when the package is used from the current directory. \directlua{ local path if resolvers and resolvers.findfile then path = resolvers.findfile("pgfplots-autonode.lua", "lua") or resolvers.findfile("pgfplots-autonode.lua", "tex") elseif kpse and kpse.find_file then path = kpse.find_file("pgfplots-autonode.lua", "lua") or kpse.find_file("pgfplots-autonode.lua", "tex") end path = path or "pgfplots-autonode.lua" pgfplots_autonode = dofile(path) } % ----------------------------------------------------------------------------- % User keys for \pgfplotsautonode. % ----------------------------------------------------------------------------- \pgfkeys{ /pgfplots/autonode/.is family, /pgfplots/autonode/.cd, preferred pos/.store in=\pgfplotsautonode@preferredpos, min pos/.store in=\pgfplotsautonode@minpos, max pos/.store in=\pgfplotsautonode@maxpos, samples/.store in=\pgfplotsautonode@samples, candidates/.store in=\pgfplotsautonode@samples, candidate strategy/.is choice, candidate strategy/uniform/.code={\def\pgfplotsautonode@candidatestrategy{uniform}}, candidate strategy/around preferred/.code={\def\pgfplotsautonode@candidatestrategy{around-preferred}}, candidate strategy/around-preferred/.code={\def\pgfplotsautonode@candidatestrategy{around-preferred}}, candidate strategy/adaptive/.code={\def\pgfplotsautonode@candidatestrategy{adaptive}}, normal shift/.store in=\pgfplotsautonode@normalshift, clearance/.store in=\pgfplotsautonode@clearance, inner sep/.store in=\pgfplotsautonode@innersep, font/.store in=\pgfplotsautonode@font, node options/.code={\def\pgfplotsautonode@nodeopts{#1}}, preferred weight/.store in=\pgfplotsautonode@preferredweight, overlap weight/.store in=\pgfplotsautonode@overlapweight, priority/.store in=\pgfplotsautonode@priority, sloped/.is if=pgfplotsautonode@sloped, sloped/.default=true, allow upside down/.is if=pgfplotsautonode@allowupsidedown, allow upside down/.default=true, default/.style={ preferred pos=.5, min pos=0, max pos=1, samples=\pgfplotsautonode@defaultcandidates, candidate strategy=\pgfplotsautonode@defaultcandidatestrategy, normal shift=0pt, clearance=1pt, inner sep=1.5pt, sloped=false, allow upside down=false, font=, node options={fill=white,draw=none,text opacity=1}, preferred weight=8, overlap weight=1000, priority=0 }, above/.style={normal shift=6pt}, below/.style={normal shift=-6pt} } % ----------------------------------------------------------------------------- % pgfplots axis-level keys. % ----------------------------------------------------------------------------- \pgfplotsset{ auto node placement/.code={% \global\pgfplotsautonode@placementenabledtrue % The key is parsed before plot registration. Initialize immediately: % appending to `execute at begin axis` here can miss that hook when PGFPlots % has already executed it, leaking label IDs into the next axis. \pgfplotsautonode@beginaxis \pgfkeysalso{% after end axis/.append code={\pgfplotsautonode@flush}% }% }, auto node debug/.is choice, auto node debug/false/.code={\pgfplotsautonode@debuglevel=0\relax}, auto node debug/off/.code={\pgfplotsautonode@debuglevel=0\relax}, auto node debug/summary/.code={\pgfplotsautonode@debuglevel=1\relax}, auto node debug/verbose/.code={\pgfplotsautonode@debuglevel=2\relax}, auto node debug/trace/.code={\pgfplotsautonode@debuglevel=3\relax}, auto node debug/.default=summary, auto node max iterations/.code={\pgfplotsautonode@maxiterations=#1\relax}, auto node algorithm/.is choice, auto node algorithm/greedy/.code={\def\pgfplotsautonode@algorithm{greedy}}, auto node algorithm/repair/.code={\def\pgfplotsautonode@algorithm{repair}}, auto node algorithm/local-search/.code={\def\pgfplotsautonode@algorithm{local-search}}, auto node algorithm/exact-small/.code={\def\pgfplotsautonode@algorithm{exact-small}}, auto node bbox mode/.is choice, auto node bbox mode/axis-aligned/.code={\def\pgfplotsautonode@bboxmode{axis-aligned}}, auto node bbox mode/oriented/.code={\def\pgfplotsautonode@bboxmode{oriented}}, auto node failure mode/.is choice, auto node failure mode/warn/.code={\def\pgfplotsautonode@failuremode{warn}}, auto node failure mode/error/.code={\def\pgfplotsautonode@failuremode{error}}, auto node failure mode/hide-low-priority/.code={\def\pgfplotsautonode@failuremode{hide-low-priority}}, auto node failure mode/allow-minimal-overlap/.code={\def\pgfplotsautonode@failuremode{allow-minimal-overlap}}, auto node candidates/.code={\def\pgfplotsautonode@defaultcandidates{#1}}, auto node candidate strategy/.is choice, auto node candidate strategy/uniform/.code={\def\pgfplotsautonode@defaultcandidatestrategy{uniform}}, auto node candidate strategy/around preferred/.code={\def\pgfplotsautonode@defaultcandidatestrategy{around-preferred}}, auto node candidate strategy/around-preferred/.code={\def\pgfplotsautonode@defaultcandidatestrategy{around-preferred}}, auto node candidate strategy/adaptive/.code={\def\pgfplotsautonode@defaultcandidatestrategy{adaptive}}, auto node border margin/.code={\def\pgfplotsautonode@bordermargin{#1}}, auto node overlap tolerance/.code={\def\pgfplotsautonode@overlaptolerance{#1}}, auto node allow outside/.is if=pgfplotsautonode@allowoutside, auto node allow outside/.default=true, auto node show bounding boxes/.is if=pgfplotsautonode@showboundingboxes, auto node show bounding boxes/.default=true, auto node show candidates/.is if=pgfplotsautonode@showcandidates, auto node show candidates/.default=true, auto node show rejected candidates/.is if=pgfplotsautonode@showrejectedcandidates, auto node show rejected candidates/.default=true, auto node exact max labels/.code={\pgfplotsautonode@exactmaxlabels=#1\relax}, auto node exact max states/.code={\pgfplotsautonode@exactmaxstates=#1\relax} } \def\pgfplotsautonode@luabool#1{\csname if#1\endcsname true\else false\fi} \def\pgfplotsautonode@configurelua{% \pgf@xa=\pgfplotsautonode@bordermargin\relax \edef\pgfplotsautonode@bordermarginpt{\pgf@sys@tonumber\pgf@xa}% \pgf@xa=\pgfplotsautonode@overlaptolerance\relax \edef\pgfplotsautonode@overlaptolerancept{\pgf@sys@tonumber\pgf@xa}% \edef\pgfplotsautonode@allowoutsidebool{\ifpgfplotsautonode@allowoutside true\else false\fi}% \edef\pgfplotsautonode@showboundingboxesbool{\ifpgfplotsautonode@showboundingboxes true\else false\fi}% \edef\pgfplotsautonode@showcandidatesbool{\ifpgfplotsautonode@showcandidates true\else false\fi}% \edef\pgfplotsautonode@showrejectedcandidatesbool{\ifpgfplotsautonode@showrejectedcandidates true\else false\fi}% \directlua{pgfplots_autonode.configure({ debug_level = tonumber("\the\pgfplotsautonode@debuglevel"), max_iterations = tonumber("\the\pgfplotsautonode@maxiterations"), algorithm = "\pgfplotsautonode@algorithm", bbox_mode = "\pgfplotsautonode@bboxmode", failure_mode = "\pgfplotsautonode@failuremode", border_margin = tonumber("\pgfplotsautonode@bordermarginpt"), overlap_tolerance = tonumber("\pgfplotsautonode@overlaptolerancept"), allow_outside = \pgfplotsautonode@allowoutsidebool, show_bounding_boxes = \pgfplotsautonode@showboundingboxesbool, show_candidates = \pgfplotsautonode@showcandidatesbool, show_rejected_candidates = \pgfplotsautonode@showrejectedcandidatesbool, exact_max_labels = tonumber("\the\pgfplotsautonode@exactmaxlabels"), exact_max_states = tonumber("\the\pgfplotsautonode@exactmaxstates") })}% } \def\pgfplotsautonode@beginaxis{% \global\pgfplotsautonode@missinghookwarnedfalse \global\pgfplotsautonode@id=0\relax \directlua{pgfplots_autonode.reset()}% \pgfplotsautonode@configurelua } % Pass the visible axis rectangle to Lua in the same physical canvas coordinate % system as the sampled candidates. rel axis cs:0,0 and rel axis cs:1,1 are the % plot-area corners, before tick labels and axis descriptions are added. \def\pgfplotsautonode@setaxisrect{% \pgf@process{\pgfplotspointrelaxisxy{0}{0}}% \pgf@xa=\pgf@x\relax \pgf@ya=\pgf@y\relax \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xa}{\pgf@ya}}}% \edef\pgfplotsautonode@rectleft{\pgf@sys@tonumber\pgf@x}% \edef\pgfplotsautonode@rectbottom{\pgf@sys@tonumber\pgf@y}% \pgf@process{\pgfplotspointrelaxisxy{1}{1}}% \pgf@xa=\pgf@x\relax \pgf@ya=\pgf@y\relax \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xa}{\pgf@ya}}}% \edef\pgfplotsautonode@rectright{\pgf@sys@tonumber\pgf@x}% \edef\pgfplotsautonode@recttop{\pgf@sys@tonumber\pgf@y}% \directlua{pgfplots_autonode.set_axis_rect( tonumber("\pgfplotsautonode@rectleft"), tonumber("\pgfplotsautonode@rectright"), tonumber("\pgfplotsautonode@rectbottom"), tonumber("\pgfplotsautonode@recttop") )}% } \def\pgfplotsautonode@flush{% % PGFPlots can execute `execute at begin axis` while it is still processing % later axis options. Synchronize once more here so the solver observes the % final axis-local values independently of key order. \pgfplotsautonode@configurelua \pgfplotsautonode@setaxisrect \pgfplotsautonode@measureall \directlua{pgfplots_autonode.solve_and_emit()}% \global\pgfplotsautonode@placementenabledfalse } % Measure after plot visualization, outside the active plot path. Interrupt % the enclosing picture before opening the scratch picture: PGF then restores % the real font selector and the nested picture cannot capture its own % \pgf@selectfont as \pgf@selectfontorig. \def\pgfplotsautonode@measurelabel#1{% \begingroup \edef\pgfplotsautonode@measureopts{\csname pgfplotsautonode@options@#1\endcsname}% \edef\pgfplotsautonode@measurefont{\csname pgfplotsautonode@font@#1\endcsname}% \edef\pgfplotsautonode@measureinnersep{\csname pgfplotsautonode@innersep@#1\endcsname}% \setbox0=\hbox{% \pgfinterruptpicture \tikzpicture \edef\pgfplotsautonode@measurepath{% \noexpand\path node[font={\pgfplotsautonode@measurefont},inner sep=\pgfplotsautonode@measureinnersep,\pgfplotsautonode@measureopts,rotate=0] at (0pt,0pt) {\expandafter\noexpand\csname pgfplotsautonode@content@#1\endcsname};% }% \pgfplotsautonode@measurepath \xdef\pgfplotsautonode@localxmin{\pgf@sys@tonumber\pgf@picminx}% \xdef\pgfplotsautonode@localxmax{\pgf@sys@tonumber\pgf@picmaxx}% \xdef\pgfplotsautonode@localymin{\pgf@sys@tonumber\pgf@picminy}% \xdef\pgfplotsautonode@localymax{\pgf@sys@tonumber\pgf@picmaxy}% \endtikzpicture \endpgfinterruptpicture }% \directlua{pgfplots_autonode.set_label_geometry( tonumber("#1"), tonumber("\pgfplotsautonode@localxmin"), tonumber("\pgfplotsautonode@localxmax"), tonumber("\pgfplotsautonode@localymin"), tonumber("\pgfplotsautonode@localymax") )}% \endgroup } \def\pgfplotsautonode@measureall{% \begingroup \pgfplotsautonode@measureindex=1\relax \loop\ifnum\pgfplotsautonode@measureindex<\numexpr\pgfplotsautonode@id+1\relax \expandafter\pgfplotsautonode@measurelabel\expandafter{\the\pgfplotsautonode@measureindex}% \advance\pgfplotsautonode@measureindex by1\relax \repeat \endgroup } % Drawing callback emitted by Lua. % #1 label id, #2 x in pt, #3 y in pt, #4 rotation angle in degrees. \def\pgfplotsautonodedraw#1#2#3#4{% \begingroup \edef\pgfplotsautonode@drawopts{\csname pgfplotsautonode@options@#1\endcsname}% \edef\pgfplotsautonode@drawfont{\csname pgfplotsautonode@font@#1\endcsname}% \edef\pgfplotsautonode@drawinnersep{\csname pgfplotsautonode@innersep@#1\endcsname}% \edef\pgfplotsautonode@next{% \endgroup \noexpand\pgfscope \noexpand\pgftransformreset \noexpand\path node[font={\pgfplotsautonode@drawfont},inner sep=\pgfplotsautonode@drawinnersep,\pgfplotsautonode@drawopts,rotate=#4]% at (#2pt,#3pt) {\expandafter\noexpand\csname pgfplotsautonode@content@#1\endcsname};% \noexpand\endpgfscope }% \pgfplotsautonode@next } % Debug visualisations. These are intentionally simple and independent of the % final node style so that they do not affect normal documents. \def\pgfplotsautonodedrawbbox#1#2#3#4#5{% \pgfscope \pgftransformreset \path[draw=orange!80!black,densely dashed,line width=.25pt] (#2pt,#3pt) rectangle (#4pt,#5pt);% \endpgfscope } \def\pgfplotsautonodedrawcandidate#1#2#3{% \pgfscope \pgftransformreset \def\pgfplotsautonode@state{#1}% \def\pgfplotsautonode@valid{valid}% \ifx\pgfplotsautonode@state\pgfplotsautonode@valid \path[draw=green!50!black,fill=green!50!black] (#2pt,#3pt) circle[radius=.65pt];% \else \path[draw=red!70!black] (#2pt,#3pt) ++(-.8pt,-.8pt) -- ++(1.6pt,1.6pt) ++(-1.6pt,0pt) -- ++(1.6pt,-1.6pt);% \fi \endpgfscope } % Public macro used as a pgfplots trailing path command: % \addplot {x^2} \pgfplotsautonode[sloped,preferred pos=.5] {$x^2$}; \def\pgfplotsautonode[#1]#2{% \pgfextra{\pgfplotsautonode@register{#1}{#2}}% } \def\pgfplotsautonode@samplecandidate#1#2{% \pgf@process{\pgfplotspointplotattime{#1}}% \pgf@xa=\pgf@x\relax \pgf@ya=\pgf@y\relax \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xa}{\pgf@ya}}}% \edef\pgfplotsautonode@canvasx{\pgf@sys@tonumber\pgf@x}% \edef\pgfplotsautonode@canvasy{\pgf@sys@tonumber\pgf@y}% \directlua{pgfplots_autonode.add_candidate( tonumber("\pgfplotsautonode@idstr"), tonumber("#1"), tonumber("\pgfplotsautonode@canvasx"), tonumber("\pgfplotsautonode@canvasy"), tonumber("#2") )}% } % Read the surveyed vertices of the current PGFPlots path. PGFPlots uses % these same serialized coordinates for \pgfplotspointplotattime. Forward its % own segment-length metric so Lua's normalized positions agree with that API. \def\pgfplotsautonode@pathstart{% \let\pgfplotsautonode@previouspoint\relax } \def\pgfplotsautonode@pathcoord{% \ifx\pgfplots@current@point@x\pgfutil@empty \let\pgfplotsautonode@previouspoint\relax \directlua{pgfplots_autonode.add_path_break(tonumber("\pgfplotsautonode@idstr"))}% \else \pgfplotsplothandlerserializepointto{\pgfplotsautonode@currentpoint}% \ifx\pgfplotsautonode@previouspoint\relax \def\pgfplotsautonode@segmentlength{0}% \else \pgfplotsplothandlersurveydifflen{\pgfplotsautonode@previouspoint}{\pgfplotsautonode@currentpoint}% \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% \edef\pgfplotsautonode@segmentlength{\pgfmathresult}% \fi \let\pgfplotsautonode@previouspoint\pgfplotsautonode@currentpoint \pgf@process{\pgfplotsaxisvisphasegetpoint}% \pgf@xa=\pgf@x\relax \pgf@ya=\pgf@y\relax \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xa}{\pgf@ya}}}% \edef\pgfplotsautonode@canvasx{\pgf@sys@tonumber\pgf@x}% \edef\pgfplotsautonode@canvasy{\pgf@sys@tonumber\pgf@y}% \directlua{pgfplots_autonode.add_path_point( tonumber("\pgfplotsautonode@idstr"), tonumber("\pgfplotsautonode@canvasx"), tonumber("\pgfplotsautonode@canvasy"), tonumber("\pgfplotsautonode@segmentlength") )}% \fi } \def\pgfplotsautonode@collectpath{% \begingroup \if1\b@pgfplots@LUA@visualization@enabled \ifx\pgfplots@plot@timer@args\relax \expandafter\gdef\expandafter\pgfplots@plot@timer@args\expandafter{% \pgfplotsutil@directlua{pgfplots.texGetSurveyedCoordsToPgfplots()}% }% \fi \let\pgfplotsaxisdeserializedatapointfrom@private=\pgfplotsaxisdeserializedatapointfrom@private@nonLUA \else \global\let\pgfplots@plot@timer@args=\pgfplots@stored@current@data \fi \let\pgfplots@coord@stream@start\pgfplotsautonode@pathstart \let\pgfplots@coord@stream@coord\pgfplotsautonode@pathcoord \let\pgfplots@coord@stream@end\relax \expandafter\pgfplots@coord@stream@foreach@NORMALIZED \expandafter{\pgfplots@plot@timer@args}% \endgroup } \long\def\pgfplotsautonode@register#1#2{% \ifpgfplotsautonode@placementenabled\else \ifpgfplotsautonode@missinghookwarned\else \global\pgfplotsautonode@missinghookwarnedtrue \immediate\write16{pgfplots-autonode warning: label registered without `auto node placement'; no automatic label can be rendered}% \fi \fi \begingroup \pgfkeys{/pgfplots/autonode/.cd,default,#1}% \global\advance\pgfplotsautonode@id by1\relax \edef\pgfplotsautonode@idstr{\the\pgfplotsautonode@id}% % Store label content and TikZ node options without expanding the content. \expandafter\gdef\csname pgfplotsautonode@content@\pgfplotsautonode@idstr\endcsname{#2}% \expandafter\global\expandafter\let\csname pgfplotsautonode@options@\pgfplotsautonode@idstr\endcsname\pgfplotsautonode@nodeopts \expandafter\global\expandafter\let\csname pgfplotsautonode@font@\pgfplotsautonode@idstr\endcsname\pgfplotsautonode@font \expandafter\global\expandafter\let\csname pgfplotsautonode@innersep@\pgfplotsautonode@idstr\endcsname\pgfplotsautonode@innersep \pgf@xa=\pgfplotsautonode@normalshift\relax \edef\pgfplotsautonode@normalshiftpt{\pgf@sys@tonumber\pgf@xa}% \pgf@xa=\pgfplotsautonode@clearance\relax \edef\pgfplotsautonode@clearancept{\pgf@sys@tonumber\pgf@xa}% \pgfmathparse{\pgfplotsautonode@preferredpos}% \let\pgfplotsautonode@preferrednumeric\pgfmathresult \pgfmathparse{\pgfplotsautonode@minpos}% \let\pgfplotsautonode@minnumeric\pgfmathresult \pgfmathparse{\pgfplotsautonode@maxpos}% \let\pgfplotsautonode@maxnumeric\pgfmathresult \pgfmathtruncatemacro\pgfplotsautonode@samplesnumeric{\pgfplotsautonode@samples}% \edef\pgfplotsautonode@slopedbool{\ifpgfplotsautonode@sloped true\else false\fi}% \edef\pgfplotsautonode@allowupsidedownbool{\ifpgfplotsautonode@allowupsidedown true\else false\fi}% \directlua{pgfplots_autonode.add_label( tonumber("\pgfplotsautonode@idstr"), 0, 0, tonumber("\pgfplotsautonode@preferrednumeric"), tonumber("\pgfplotsautonode@normalshiftpt"), tonumber("\pgfplotsautonode@clearancept"), \pgfplotsautonode@slopedbool, \pgfplotsautonode@allowupsidedownbool, tonumber("\pgfplotsautonode@preferredweight"), tonumber("\pgfplotsautonode@overlapweight"), tonumber("\pgfplotsautonode@priority") )}% \pgfplotsautonode@setaxisrect \pgfplotsautonode@collectpath % Lua clips the surveyed path in canvas coordinates and requests positions % only on its visible portions. Final samples still use PGFPlots' own % point-at-time function to preserve its path interpolation. \directlua{pgfplots_autonode.emit_visible_candidate_positions( tonumber("\pgfplotsautonode@idstr"), tonumber("\pgfplotsautonode@preferrednumeric"), tonumber("\pgfplotsautonode@minnumeric"), tonumber("\pgfplotsautonode@maxnumeric"), tonumber("\pgfplotsautonode@samplesnumeric"), "\pgfplotsautonode@candidatestrategy" )}% \endgroup } \catcode`\@=\csname pgfplotsautonode@oldatcatcode\endcsname\relax \endinput .