3

I've made a plot like the one below to show a distribution of values in the dependent variable versus the change of the independent variable.

\documentclass[varwidth]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{fillbetween}
\usepackage{tikz}

\pgfplotstableread{
x min q1 med q3 max
1 0 2 4 6 8
2 2 4 5 6 8
3 1 3 5 7 9
}\data%

\begin{document}
\begin{tikzpicture}
  \begin{axis}[title=Example,
    xlabel=x,
    ylabel=y,
    ]
    \addplot[blue, dashed] table [x=x, y=min] {\data};
    \addplot[blue, dotted, name path global=q1] table [x=x, y=q1] {\data};
    \addplot[blue, solid] table [x=x, y=med] {\data};
    \addplot[blue, dotted, name path global=q3] table [x=x, y=q3] {\data};
    \addplot[blue, dashed] table [x=x, y=max] {\data};
    \addplot[blue, fill opacity=0.3] fill between[of=q1 and q3];
  \end{axis}
\end{tikzpicture}

\end{document}

Image showing resulting PDF plot from code, above

I'd like to have a legend like the following,

Example legend

Is that possible? How?

Edit: adding my full solution

The solution below got most of what I was looking for, and with a few minor edits I was able to get it perfect. (Well, the image below isn't quite perfect--just realized I switched Q1 and Q3.)

Final result showing correct legend

I increased the size of the custom legend entry from 0.1cm to 0.4cm,

\pgfplotsset{custom legend/.style={%
                /pgfplots/legend image code/.code={%
                        \path[##1] (0cm,-.4cm) rectangle (0.6cm,0.4cm);
                        \draw[dotted] (0cm,-0.4cm) -- (0.6cm,-0.4cm)
                         (0cm,0.4cm) -- (0.6cm,0.4cm);
                         \draw[blue] (0cm,0cm) -- (0.6cm,0cm);
                }}}

And made the corresponding legend entry three lines,

\begin{axis}[title=Example,
  xlabel=x,
  ylabel=y,
  legend style={cells={align=left}},
  ]
  \addlegendimage{blue,dashed}
  \addlegendentry[font=\sffamily]{Maximum}
  \addlegendimage{custom legend,draw=none,fill=blue,fill opacity=0.3}
  \addlegendentry[xshift=-2mm,font=\sffamily]{Q1 \\ Median \\ Q3}
  \addlegendimage{blue,dashed}
  \addlegendentry[xshift=-0.2mm,font=\sffamily]{Minimum}
...
3

Here is a proposal. I looked uparea legend in pgfplots.code.tex and used it as a basis for custom legend, which comes already close to what you want, I think, and can be further customized. (I am pretty sure I have seen an answer using similar tricks but even after some long search I couldn't find it. I am definitely not claiming that I am the first one doing these tricks.) Anyway, the result of a quick customization (after a long search without hits) is

\documentclass[varwidth]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{fillbetween}
\usepackage{tikz}

\pgfplotstableread{
x min q1 med q3 max
1 0 2 4 6 8
2 2 4 5 6 8
3 1 3 5 7 9
}\data%
\pgfplotsset{custom legend/.style={%
                /pgfplots/legend image code/.code={%
                        \path[##1] (0cm,-0.1cm) rectangle (0.6cm,0.1cm);
                        \draw[dotted] (0cm,-0.1cm) -- (0.6cm,-0.1cm)
                         (0cm,0.1cm) -- (0.6cm,0.1cm);
                         \draw[blue] (0cm,0cm) -- (0.6cm,0cm);
                }}}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[title=Example,
    xlabel=x,
    ylabel=y,
    ]
    \addlegendimage{blue,dashed}
    \addlegendentry[font=\sffamily]{Maximum}
    \addlegendimage{custom legend,draw=none,fill=blue,fill opacity=0.3}
    \addlegendentry[xshift=-2mm,font=\sffamily]{Median}
    \addlegendimage{blue,dashed}
    \addlegendentry[xshift=-0.2mm,font=\sffamily]{Minimum}
    \addplot[blue, dashed] table [x=x, y=min] {\data};
    \addplot[blue, dotted, name path global=q1] table [x=x, y=q1] {\data};
    \addplot[blue, solid] table [x=x, y=med] {\data};
    \addplot[blue, dotted, name path global=q3] table [x=x, y=q3] {\data};
    \addplot[blue, dashed] table [x=x, y=max] {\data};
    \addplot[blue, fill opacity=0.3] fill between[of=q1 and q3];
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

After some amount of hibernation I will be happy to assist you in further customization, if needed.

  • 1
    Awesome! This got me on the right path, and with a few small changes I got exactly what I wanted. I increased the size of the custom image in the y dimension, and made the corresponding text a three-line entry (as described in this question). – john_stech Nov 25 '18 at 15:00
  • @john_stech Thanks! (I was too tired last night to do the tuning, and I am really glad you got what I wanted. I'm wondering you want to add the information what you did to your question, other users might find that useful.) – user121799 Nov 25 '18 at 17:18

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.