7

I am trying to make a histogram with the fitted curve plotted on it. Here's the mwe:

 \documentclass[a4paper]{scrartcl}
    \usepackage{tikz}
    \usepackage{pgfplots,pgfplotstable}
    \usepackage{filecontents}
    \pgfplotsset{compat=1.10}
    \usepackage[active,tightpage]{preview}
    \setlength\PreviewBorder{2pt}
    \newcommand{\plots}{0.611201}
    \newcommand{\plotm}{2.19882}
    \begin{filecontents}{data.dat}
    2 0.0629921259843
    3 0.0236220472441
    4 0.0314960629921
    5 0.125984251969
    6 0.0629921259843
    7 0.102362204724
    8 0.110236220472
    9 0.0551181102362
    10 0.0629921259843
    11 0.0314960629921
    12 0.0236220472441
    13 0.0314960629921
    14 0.0629921259843
    15 0.0551181102362
    16 0.0393700787402
    17 0.0472440944882
    18 0.00787401574803
    19 0.0393700787402
    24 0.00787401574803
    27 0.00787401574803
    33 0.00787401574803
    \end{filecontents}
    \begin{document}
    \begin{preview}

    \begin{tikzpicture}
    \begin{axis}[
    yticklabel style={/pgf/number format/fixed},
    scaled y ticks = false,
    minor y tick num={1},
    xtick pos=left,
    legend cell align = left,
    legend style={draw=none},
    xlabel = {group size},
    ylabel = {ratio}
    ]
    \addplot[blue,ybar,fill, fill opacity=0.3, bar width = 0.8,] table {data.dat};
    \addplot[red, line width = 1,domain=1:40,samples=100] {1/(x*sqrt(2*pi)*\plots)*exp(-(ln(x)-\plotm)^2/(2*\plots^2))};
    \legend{empirical,lognormal fit}
    \end{axis}
    \end{tikzpicture}
    \end{preview}
    \end{document}

enter image description here

As you can see, the legend is not really good. How can I change the legend so it looks more like this?

enter image description here

1 Answer 1

8

There are a couple of ways of solving this. One way is to move the ybar option from the \addplot to the axis. The same key means slightly different things in the two locations, in the axis it refers to /pgfplots/ybar, while in the \addplot it refers to /tikz/ybar. It would appear that these lead to different behaviours for the legends, though I have not looked at precisely how they're defined.

Of course, when you add ybar to the axis, it will affect all \addplots, so you must also add sharp plot to the line plot. sharp plot is the default style for addplot, it draws a line with markers by default.

Result and complete code first, second option below:

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usepackage{filecontents}
\pgfplotsset{compat=1.10}
\newcommand{\plots}{0.611201}
\newcommand{\plotm}{2.19882}
\begin{filecontents}{data.dat}
2 0.0629921259843
3 0.0236220472441
4 0.0314960629921
5 0.125984251969
6 0.0629921259843
7 0.102362204724
8 0.110236220472
9 0.0551181102362
10 0.0629921259843
11 0.0314960629921
12 0.0236220472441
13 0.0314960629921
14 0.0629921259843
15 0.0551181102362
16 0.0393700787402
17 0.0472440944882
18 0.00787401574803
19 0.0393700787402
24 0.00787401574803
27 0.00787401574803
33 0.00787401574803
\end{filecontents}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
yticklabel style={/pgf/number format/fixed},
scaled y ticks = false,
minor y tick num={1},
xtick pos=left,
legend cell align = left,
legend style={draw=none},
xlabel = {group size},
ylabel = {ratio},
ybar
]
\addplot[blue,ybar,fill, fill opacity=0.3, bar width = 0.8] table {data.dat};
\addplot[sharp plot,red, line width = 1,domain=1:40,samples=100,line legend] {1/(x*sqrt(2*pi)*\plots)*exp(-(ln(x)-\plotm)^2/(2*\plots^2))};
\legend{empirical,lognormal fit}
\end{axis}
\end{tikzpicture}
\end{document}

Second option

Another way is to simply add area legend to the options of the \addplot command for the ybar plot. This tells pgfplots to create a filled rectangle as the legend entry, instead of just a line, as in the prefered example. You can also use ybar legend instead of area legend, which will make it like in the first example. You can find the definitions of how the legend entries are created in the manual.

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usepackage{filecontents}
\pgfplotsset{compat=1.10}
\newcommand{\plots}{0.611201}
\newcommand{\plotm}{2.19882}
\begin{filecontents}{data.dat}
2 0.0629921259843
3 0.0236220472441
4 0.0314960629921
5 0.125984251969
6 0.0629921259843
7 0.102362204724
8 0.110236220472
9 0.0551181102362
10 0.0629921259843
11 0.0314960629921
12 0.0236220472441
13 0.0314960629921
14 0.0629921259843
15 0.0551181102362
16 0.0393700787402
17 0.0472440944882
18 0.00787401574803
19 0.0393700787402
24 0.00787401574803
27 0.00787401574803
33 0.00787401574803
\end{filecontents}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
yticklabel style={/pgf/number format/fixed},
scaled y ticks = false,
minor y tick num={1},
xtick pos=left,
legend cell align = left,
legend style={draw=none},
xlabel = {group size},
ylabel = {ratio}
]
\addplot[blue,ybar,fill, fill opacity=0.3, bar width = 0.8,area legend] table {data.dat};
\addplot[red, line width = 1,domain=1:40,samples=100] {1/(x*sqrt(2*pi)*\plots)*exp(-(ln(x)-\plotm)^2/(2*\plots^2))};
\legend{empirical,lognormal fit}
\end{axis}
\end{tikzpicture}
\end{document}

Third option (dealing with alignment issues)

As can be seen, in the first option, the legend for the histogram is misaligned. We can fix this by overriding the default behavior of ybar legend. The default behavior (see manual) is

\pgfplotsset{
/pgfplots/xbar legend/.style={
/pgfplots/legend image code/.code={%
\draw[##1,/tikz/.cd,bar width=3pt,yshift=-0.2em,bar shift=0pt]
plot coordinates {(0cm,0.8em) (2*\pgfplotbarwidth,0.6em)};},
},
}

Here's an example with the complete code for a much nicer looking ybar legend

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usepackage{filecontents}
\pgfplotsset{compat=1.10}
\newcommand{\plots}{0.611201}
\newcommand{\plotm}{2.19882}
\begin{filecontents}{data.dat}
2 0.0629921259843
3 0.0236220472441
4 0.0314960629921
5 0.125984251969
6 0.0629921259843
7 0.102362204724
8 0.110236220472
9 0.0551181102362
10 0.0629921259843
11 0.0314960629921
12 0.0236220472441
13 0.0314960629921
14 0.0629921259843
15 0.0551181102362
16 0.0393700787402
17 0.0472440944882
18 0.00787401574803
19 0.0393700787402
24 0.00787401574803
27 0.00787401574803
33 0.00787401574803
\end{filecontents}
\pgfplotsset{
/pgfplots/ybar legend/.style={
/pgfplots/legend image code/.code={%
\draw[##1,/tikz/.cd,bar width=0.1cm,yshift=-0.2em,bar shift=0.5*\pgfplotbarwidth]
plot coordinates {(0.5*\pgfplotbarwidth,0.6em) (2.5*\pgfplotbarwidth,0.4em) (4.5*\pgfplotbarwidth,0.2em)};},
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
yticklabel style={/pgf/number format/fixed},
scaled y ticks = false,
minor y tick num={1},
xtick pos=left,
legend cell align = left,
legend style={draw=none},
xlabel = {group size},
ylabel = {ratio}
]
\addplot[blue,ybar,fill, fill opacity=0.3, bar width = 0.8,ybar legend] table {data.dat};
\addplot[red, line width = 1,domain=1:40,samples=100] {1/(x*sqrt(2*pi)*\plots)*exp(-(ln(x)-\plotm)^2/(2*\plots^2))};
\legend{empirical,lognormal fit}
\end{axis}
\end{tikzpicture}
\end{document}
10
  • could you explain the original behaviour and why your solution is necessary to fix it?
    – ArTourter
    Jun 27, 2015 at 0:01
  • @ArTourter No. I don't know why pgfplots doesn't default to area legend for the ybar plot. Jun 27, 2015 at 7:14
  • do you know what it defaults to? it is rather weird!
    – ArTourter
    Jun 27, 2015 at 10:17
  • @ArTourter I updated my answer. Jun 27, 2015 at 10:33
  • @TorbjørnT. Thanks! This kind of looks like a bug then. Anyway, I would disagree, that the first version looks better, since the histogram legend and the line legend are seriously missaligned. Three columns, with the tallest being as tall as the text and centered so it is aligned with the line would be better than the second though. I'm looking at how to do just that, although that might come up as a new question :D
    – fbence
    Jun 29, 2015 at 13:16

You must log in to answer this question.

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