3

I frequently create plots with \addplot using a lot of optional arguments, making it difficult to keep the code consistent. I have a few repeating plotstyles so I tried to implement a new macro that can be used like:

\newaddplot[style=mystyle1,draw=red]{mydatafile.txt};

I want to retain the structure and keys of the original \addplot function and also add new keys. My approach below uses pgfkeys to parse the key-value pairs of \newaddplot, handle my new keys and pass the rest to the \addplot command inside \newaddplot. The MWE uses "draw" and "offset" as an example of an existing and a new key.

\documentclass{standalone} 
\usepackage[english]{babel}
\usepackage{pgfplots,pgfkeys}\pgfplotsset{compat=newest}

\begin{document}%

\newcommand\offset{0}        
\pgfkeys{
/newaddplot/.is family, /newaddplot,
default/.style = {offset=0},
offset/.code = {\renewcommand\offset{#1}},
.unknown/.code={
\let\currname\pgfkeyscurrentname
\let\currval\pgfkeyscurrentvalue
\ifx#1\pgfkeysnovalue
\pgfqkeys{/pgfplots}{remainingkeys/.append style/.expand once={\currname}}
\else
\pgfqkeys{/pgfplots}{remainingkeys/.append style/.expand twice={\expandafter\currname\expandafter=\currval}}
\fi
}}    

\newcommand\newaddplot[1][]{
\pgfqkeys{/pgfplots}{remainingkeys/.style={}}% reset remainingkeys
% \pgfplotsextra{ %uncomment here ...
\pgfkeys{/newaddplot,default,#1}%set default values and parse key-value pairs
% } % ... and here fixes colors but ignores offset
\addplot[/pgfplots/remainingkeys] coordinates {(0,0+\offset)(1,1+\offset)} % use parsed keys for plot
}

\begin{tikzpicture}     
    \begin{axis}    
        \newaddplot[draw=red,ultra thick,offset=1];
        \newaddplot[draw=blue,dashed];
    \end{axis}
\end{tikzpicture}  

\end{document}

The problem is that the attributes of the last \newaddplot are used for all plots (here draw=blue,dashed). After some research i found that this is because "any drawing commands inside of an axis need to be postponed until the axis is complete" (pgfplotsmanual Chapter 8.3). Using \pgfplotsextra (uncommenting the two lines in the MWE) uses ALL attributes specified before, i.e. the "ultra thick" from the first plot is also applied to the second plot. In Addition the offset is not working anymore. output with and without pgfplotsextra

How can I make sure that the keys only affect the corresponding plot?

  • Your top line is perfectly legitimate if you remove style= part. – percusse Jun 21 '15 at 23:16
  • @percusse The style=mystyle1 is just an example of a new custom key, like offset in the MWE. However the value of style would change e.g. the color, fill and marks of the plot all at once. – dukeeloo Jun 22 '15 at 13:34
0

I came up with an solution though i can not judge if this is a "good way" to solve the issue. Comments are appreciated.

Instead of appending the unknown keys to /pgfplots/remainingkeys I use a counter to define a seperate style for each \newaddplot

The trick is to make sure that the counter is expanded before pgfplots starts scanning for \addplot. The details can be found here

http://www.mrunix.de/forums/archive/index.php/t-75727.html

in the answer of Christian Feuersänger.

Here is the code:

\documentclass{standalone} 
\usepackage[english]{babel}
\usepackage{pgfplots,pgfkeys}\pgfplotsset{compat=newest}    

\begin{document}%

\newcommand\offset{0}
\newcounter{newaddplotcounter}    

\pgfkeys{
/newaddplot/.is family, /newaddplot,
default/.style = {offset=0,draw=red},
offset/.code = {\renewcommand\offset{#1}},
.unknown/.code={
\let\currname\pgfkeyscurrentname
\let\currval\pgfkeyscurrentvalue
\ifx#1\pgfkeysnovalue
\pgfqkeys{/pgfplots}{newaddplotstyle no \thenewaddplotcounter/.append style/.expand once={\currname}}
\else
\pgfqkeys{/pgfplots}{newaddplotstyle no \thenewaddplotcounter/.append style/.expand twice={\expandafter\currname\expandafter=\currval}}
\fi
}}        

\newcommand\newaddplot[1][]{
\stepcounter{newaddplotcounter}
\pgfkeys{/newaddplot,default,#1}%set default valuse and parse key-value pairs
\edef\TEMP{\noexpand\addplot[newaddplotstyle no \thenewaddplotcounter] coordinates {(0,0+\offset)(1,1+\offset)}} % use parsed keys for plot    
%\show\TEMP
\TEMP
}  

\begin{tikzpicture}     
    \begin{axis}   
        \setcounter{newaddplotcounter}{-1}
        \newaddplot[offset=1];
        \newaddplot[offset=.5,ultra thick,dashed,draw=green];
        \newaddplot[dashed,draw=red];         
    \end{axis}
\end{tikzpicture}

\end{document}    

And here the result:enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.