6

I have a set of data to plot where I'd like groups of N consecutive plots with the same style. Options I've considered:

Here's an example, with two groups of 3 plots, that does what I want using this last method:

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\begin{document}
    \begin{tikzpicture}
            \begin{axis}[
            ]
                    % First group of identical plots
                    \addplot+ [domain=-1:2, samples=10] {1*x+1};
                    \pgfplotsset{cycle list shift=-1}
                    \addplot+ [domain=-1:2, samples=10] {1*x+2};
                    \pgfplotsset{cycle list shift=-2}
                    \addplot+ [domain=-1:2, samples=10] {1*x+3};
                    % Second group of identical plots
                    \addplot+ [domain=-1:2, samples=10] {2*x+1};
                    \pgfplotsset{cycle list shift=-3}
                    \addplot+ [domain=-1:2, samples=10] {2*x+2};
                    \pgfplotsset{cycle list shift=-4}
                    \addplot+ [domain=-1:2, samples=10] {2*x+3};
                    % and so on... I have a dozen of sets of 5 plots. It would get tedious.
            \end{axis}
    \end{tikzpicture}
\end{document}

Two groups of three plots

I'd like something cleaner and automated, maybe with this type of syntax:

cycle multi list={%
        color list\nextlist
        [5 of]mark list
}

But I can't figure out how!

Edit: I can't figure out either a proper method for building the legend, with only every N plots too.

6
  • I've added the legend in the question... Tell me if you think it should go to a separate post.
    – user122824
    Jan 20, 2017 at 6:34
  • Some doubts: (1) Does all your Groups have the same number of plots? (e.g. in your example there are 2 Groups of 3 plots each). (2) Do you want to do it with \foreach? And (3) Are you going to use legends? Jan 20, 2017 at 6:35
  • There are 7 \addplots given in the code which give (for me) another resulting image. Please update at least one of them. Jan 20, 2017 at 6:40
  • @Guilherme Zanotelli (1) In the case I have, only the last group has a different number of plots. A solution able to handle that would be even better, but I don't mind playing around manually a bit for this special extra-case. (2) \foreach is fine, but I thought I'd be easier with cycle list. In the real case, I'm using data from the same text file, x axis is the same for every one, and y axis is read from different columns, something like table[x=myX, y=groupID_plotID] (3) Yes, I use legends, with every N plots wanted in it.
    – user122824
    Jan 20, 2017 at 6:46
  • @Stefan Pinnow you're right, edited.
    – user122824
    Jan 20, 2017 at 6:50

2 Answers 2

2

As far as I've seen you interpreted the answer from percusse to How can I plot two lines in the same style (using cycle lists) with pgfplots? wrongly. You should not add the plots for one Group and then for the next Group and so on. You should add the first plot of all Groups, then the second and so on:

\addplot 1 from Group 1
\addplot 1 from Group 2
\addplot 1 from Group 3
\addplot 1 from Group 4 ... then
\pgfplotsset{cycle list shift=-<number of Groups>}

But this can be made into an environment, see if this works for you (note that to get the legend right just add legends to the first plots, like below):

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\newcounter{plotscount}\setcounter{plotscount}{0}
\newcommand*{\nextplots}{\stepplots\pgfplotsset{cycle list shift=-\theplotscount}}
\newenvironment{groupofplots}[1]{\def\stepplots{\addtocounter{plotscount}{#1}}}{\setcounter{plotscount}{0}}
\begin{document}
  \begin{tikzpicture}
    \begin{axis}[domain=-1:2, samples=10]
      % First plot of each group
      \begin{groupofplots}{2}
        \addplot {1*x+1};\addlegendentry{Style 1}
        \addplot {2*x+1};\addlegendentry{Style 2}
        % Second plot of each group
        \nextplots
        \addplot {1*x+2};
        \addplot {2*x+2};
        % Third plot of each group
        \nextplots
        \addplot {1*x+3};
        \addplot {2*x+3};
      \end{groupofplots}
    \end{axis}
  \end{tikzpicture}
\end{document}

EDIT

In fact you can use cycle multi list just as you mentioned:

cycle multi list={color\nextlist [N of]mark list}

A drawback of this method is the legends, I couldn't get it to work but with the inputs from Stefan Pinnow in the comments below it's possible to provide empty legends for the plots which have the same style (with the exception of one, of course).

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\begin{document}
  \begin{tikzpicture}
    \begin{axis}[
        domain=-1:2,
        samples=10,
        cycle multi list={color\nextlist [3 of]mark list}]
        \addplot {1*x+1};
        \addplot {1*x+2};
        \addplot {1*x+3};
        \addplot {2*x+4};
        \addplot {2*x+5};
        \addplot {2*x+6};
        \addplot {3*x+7};
        \addplot {3*x+8};
        \addplot {3*x+9};
        \legend{Style 1,,,Style 2,,,Style 3}
    \end{axis}
  \end{tikzpicture}
\end{document}

enter image description here

15
  • Thanks for that option. I think there's a typo in the legend: it should read: \addplot {2*x+1};\addlegendentry{Style 2 } but edits must be at least 6 char. Using percusse's suggestion this way is not very handy for me here, to handle the last group with less cases. I'll see if someone comes-up with a cycle multi solution.
    – user122824
    Jan 20, 2017 at 8:15
  • Yep, typo! And there you go, cycle multi list solution. But without legend... I couldn't solve that one :( Jan 20, 2017 at 8:19
  • Yep, that's what I feared... cyle multi looks like the right way to go, but hacking around gets you where you want.
    – user122824
    Jan 20, 2017 at 9:10
  • Here are my comments to your solution ;) 1. What do you need \label{style2} for? And the legend isn't working, because the only thing relevant for \addlegendentry is the order of that entries and are independent of everything else. That means that they don't belong to the previous \addplot command. (Give it a try and put them before everything or at the end or whatever you like. Add another \addlengendentry anywhere and the last one (of the then 4) will show the "red" style.) That is why I prefer the forget plot solution. ... Jan 20, 2017 at 9:42
  • 1
    ... But if you want to use just a few that are already declared in the mark list cycle list you could also just state [3 of]mark list. Jan 20, 2017 at 10:29
4

I think using the forget plot feature results in a quite simple solution ...

But because you didn't provide some dummy data table nor did you tell us where your legend entries are coming from I just give an example here, which you can hopefully adapt to your needs. Otherwise please be more specific in the question and edit it accordingly.

For more details on how the solution works, please have a look at the comments in the code.

% used PGFPlots v1.14
    % just some dummy data
    \begin{filecontents}{test.txt}
        x   g1p1    g1p2    g1p3    g2p1    g2p2    g2p3    g3p1    g3p2
        0.0 0.00    0.25    0.50    1.00    1.25    1.50    2.00    2.25
        0.5 0.25    0.50    0.75    1.50    1.75    2.00    3.00    3.25
        1.0 0.50    0.75    1.00    2.00    2.25    2.50    4.00    4.25
        1.5 0.75    1.00    1.25    2.50    2.75    3.00    5.00    5.25
        2.0 1.00    1.25    1.50    3.00    3.25    3.50    6.00    6.25
        2.5 1.25    1.50    1.75    3.50    3.75    4.00    7.00    7.25
    \end{filecontents}
\documentclass[border=5pt]{standalone}
% to provide the `\ifnumequal' command
% (inspired by <http://texwelt.de/wissen/fragen/5066>)
\usepackage{etoolbox}
\usepackage{pgfplots}
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            legend pos=north west,
        ]
            % loop through the groups
            \foreach \g in {1,...,2} {
                % loop through the plots of the group
                \foreach \p [count=\pi] in {1,...,3} {
                    % if the current plot loop is the last one, i.e. no 3
                    % then don't forget the plot and add the legend entry
                    \ifnumequal{\pi}{3}{
                        \addplot table [x=x,y=g\g p\p] {test.txt};
                            \addlegendentryexpanded{g\g p\p}
                    % else forget the plot
                    % (that means, use the current cycle list style without
                    %  increasing the counter and don't account for a legend
                    %  entry)
                    }{
                        \addplot+ [forget plot]
                            table [x=x,y=g\g p\p] {test.txt};
                    }
                }
            }
            % here the same in for your last special case where no
            % "group" loop is needed any more
            \foreach \p [count=\pi] in {1,...,2} {
                \ifnumequal{\p}{2}{
                    \addplot table [x=x,y=g3p\p] {test.txt};
                        \addlegendentryexpanded{g3p\p}
                }{
                    \addplot+ [forget plot]
                        table [x=x,y=g3p\p] {test.txt};
                }
            }
        \end{axis}
    \end{tikzpicture}
\end{document}

image showing the result of above code

6
  • (+1) I know in your MWE case it does not matter but didn't you mean to put \pi inside \ifnumequal instead of \p? If not then count=\pi is useless... Jan 20, 2017 at 9:27
  • @GuilhermeZanotelli, of course. Thanks for the hint. Jan 20, 2017 at 9:36
  • you can also use \ifnum\p=2\relax .... \else .... \fi with TeX
    – percusse
    Jan 20, 2017 at 9:47
  • @percusse, thanks for the hint. That is the stuff I don't know anything about :-/ Jan 20, 2017 at 9:52
  • Spending time here does that to you :P
    – percusse
    Jan 20, 2017 at 9:53

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.