1

How can I fill each pgfplots box with different predefined colors? The code below from https://www.latex4technics.com/?note=7WU2A1.

    \documentclass{minimal}
    \usepackage{pgfplots}
    \usepackage{filecontents}

    \begin{filecontents}{testdata.dat}
     0 1 1.2 0.4 1.5 0.2
     1 2 2.3 1.5 2.7 1
     2 0.7 1.4 0.5 1.9 0.1
     3 1 1.2 0.4 1.5 0.2
     4 2 2.3 1.5 2.7 1
     5 0.7 1.4 0.5 1.9 0.1
    \end{filecontents}
    

    \pgfplotsset{
     box plot width/.initial=1em,
     box plot/.style={
        /pgfplots/.cd,
        black,
        only marks,
        mark=-,
        mark size=\pgfkeysvalueof{/pgfplots/box plot width},
        /pgfplots/error bars/.cd,
        y dir=plus,
        y explicit,
     },
     box plot box/.style={
        /pgfplots/error bars/draw error bar/.code 2 args={%
            \draw  ##1 -- ++(\pgfkeysvalueof{/pgfplots/box plot width},0pt) |- ##2 -- ++(-\pgfkeysvalueof{/pgfplots/box plot width},0pt) |- ##1 -- cycle;
        },
        /pgfplots/table/.cd,
        y index=2,
        y error expr={\thisrowno{3}-\thisrowno{2}},
        /pgfplots/box plot
     },
     box plot top whisker/.style={
        /pgfplots/error bars/draw error bar/.code 2 args={%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark}%
            {\pgfplotserrorbarsmark}%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark options}%
            {\pgfplotserrorbarsmarkopts}%
            \path ##1 -- ##2;
        },
        /pgfplots/table/.cd,
        y index=4,
        y error expr={\thisrowno{2}-\thisrowno{4}},
        /pgfplots/box plot
     },
     box plot bottom whisker/.style={
        /pgfplots/error bars/draw error bar/.code 2 args={%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark}%
            {\pgfplotserrorbarsmark}%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark options}%
            {\pgfplotserrorbarsmarkopts}%
            \path ##1 -- ##2;
        },
        /pgfplots/table/.cd,
        y index=5,
        y error expr={\thisrowno{3}-\thisrowno{5}},
        /pgfplots/box plot
     },
     box plot median/.style={
        /pgfplots/box plot
     }
    }

    \begin{document}
    \begin{tikzpicture}
    \begin{axis} [enlarge x limits=0.5,xtick=data, box plot width=0.5em]
     \addplot [box plot median] table {testdata.dat};
     \addplot [box plot box] table {testdata.dat};
     \addplot [box plot top whisker] table {testdata.dat};
     \addplot [box plot bottom whisker] table {testdata.dat};
    \end{axis}
    \end{tikzpicture}
    \end{document}

enter image description here

7
  • The code seems complicated considering the output. You should provide some context. Questions: 1) I don't really understand the connection between the data and the six boxes (apart from the fact that there are six rows numbered from 0 to 5). 2) Do you want to color each box completely, or only the top or bottom part? 3) Is there a connection between the color of each box and the data on the corresponding row? 4) Finally, why do you use filecontents?
    – Daniel N
    Jan 23, 2023 at 3:03
  • Moreover, the rows are two by two identical (with corresponding identical boxes). Is this desired or only an accident?
    – Daniel N
    Jan 23, 2023 at 3:08
  • @DanielN I needed to visualize many scientific experiment results with box & whisker plots but I only had basic LaTex knowledge but pgfplots . So I tried to find a LaTex template to create plots quickly and I ran into that code. I didn't write it. I thought maybe I could adapt the code for my situation however it was challenging than I expected. 1) The first column of the data indicates index, second column median, third and fourth column, box plot limits and remaining whiskers. 2) Yes, each box completely with different colors. 3) Yes, there is. Each data row has specific color code.
    – Ugurcan
    Jan 23, 2023 at 6:44
  • 4) It was only for example. 5) Again, it is an example. I did it on purpose.
    – Ugurcan
    Jan 23, 2023 at 6:46
  • OK! The LaTeX/TikZ solution for the drawings is doable. There is a remaining question from my point of view: How do you recuperate the data to perform the drawings? Will the data be in an another file? Will the data be written down in the drawing's file? Then you say that the colour code of each row will be there... Explicitly, or will it be inferred from the data?
    – Daniel N
    Jan 23, 2023 at 10:24

1 Answer 1

1

enter image description here

The solution (i.e. the drawing) is based on a pic element boxWW which takes 7 arguments; the six numbers of a row and the colour.

The data is read from an exterior file through a \csvreader command. So, as it is, the solution needs the package csvimple. Of course, if the data is provided differently, the code should change accordingly.

With the command filecontents a data file is constructed to obtain an example (almost the one appearing in the question).

I couldn't figure out how the colours will be provided either; so I improvised with a function based on the numbers from each row. It is not very interesting, but it is based on the rgb code; you could change it easily if need be.

The code

\documentclass[10pt, margin=17pt]{standalone}
\usepackage{csvsimple}
\usepackage{filecontents}

\usepackage{tikz}
\usetikzlibrary{math, calc}

\begin{document}

\begin{filecontents}{zBoxes.dat}
 0, 1, 1.2, 0.4, 1.5, 0.2
 1, 2, 2.3, 1.5, 2.7, 1
 2, 0.7, 1.4, 0.5, 1.9, 0.1
 3, 1, 1.4, 0.4, 1.6, 0.2
 4, 2, 2.3, 1.5, 2.7, 1
 5, 0.7, 1.4, 0.5, 1.9, 0.1
\end{filecontents}

\tikzset{%
  pics/boxWW/.style n args={7}{% ... / color
    code={%
      \path (0, #2) coordinate (M);
      \path (0, #3) coordinate (T);
      \path (0, #4) coordinate (B);
      \draw[fill=#7] ($(B) +(-1ex, 0)$) rectangle ($(T) +(1ex, 0)$);
      \draw (M) ++(-1ex, 0) -- ++(2ex, 0);
      \draw (T) -- (0, #5) ++(-1ex, 0) -- ++(2ex, 0);
      \draw (B) -- (0, #6) ++(-1ex, 0) -- ++(2ex, 0);
    }
  }
}
\begin{tikzpicture}[every node/.style={inner sep=0}]
  % the axes
  \draw (-1.1, 0) -- (6, 0);
  \draw (-1, 0) -- ++(0, 3);
  \foreach \i in {-1, ..., 5}{%
    \draw[very thin] (\i, 0) -- ++(0, -3pt) node[pos=1.7, below] {\i};
  }
  \foreach \j in {0, 1, 2}{%
    \draw[very thin] (-1, \j) ++(6pt, 0) -- ++(-8pt, 0) node[pos=1.3, left] {\j};
  }

  % boxes with whiskers
  \csvreader[no head]{zBoxes.dat}{%
    1=\bno, 2=\bmed, 3=\bmax, 4=\bmin, 5=\bwmax, 6=\bwmin}
  {%
    \tikzmath{% color constants
      real \tmpr, \tmpg, \tmpb;
      \tmpb = \bwmin/\bwmax;
      \tmpg = \bmin/\bwmax;
      \tmpr = \bmax/\bwmax;
    }
    \xdefinecolor{tmp}{rgb}{\tmpr,\tmpg,\tmpb}
    \draw (\bno, 0) pic {boxWW={\bno}{\bmed}{\bmax}{\bmin}{\bwmax}{\bwmin}{tmp}};
  }
\end{tikzpicture}
\end{document}
1
  • This is awesome. Thanks Daniel! :)
    – Ugurcan
    Jan 24, 2023 at 14:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .