10

The following code plots a histogram using pgfplots.

\documentclass[a4paper]{article}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{tikzpicture}
  \centering
  \begin{axis}[
    ybar,
    enlargelimits=0.15,
    legend style={at={(0.5,-0.15)},
    anchor=north,legend columns=-1},
    ylabel={\#percentage},
    symbolic x coords={mod2,mod3,mod5,mod7,mod11,mod13,mod17,mod19,mod23},
    xtick=data,
    nodes near coords,
    nodes near coords align={vertical},
    ]
    \addplot coordinates {(mod2,75.4064) (mod3,89.7961) (mod5,94.4597)
      (mod7,96.6786) (mod11,97.5600) (mod13,98.2339)
      (mod17,98.6138) (mod19,98.9129) (mod23,99.0970)};
    \addplot coordinates {(mod2,30.5101) (mod3,34.5384) (mod5,36.3324)
      (mod7,37.3570) (mod11,37.9158) (mod13,38.3514)
      (mod17,38.6484) (mod19,38.9125) (mod23,39.1067)};
    \legend{Residue,non-Residue}
  \end{axis}
\end{tikzpicture}

\end{document}

The problem, however, is that the output looks something like this.

Example Histogram

Is there a way of spacing the x-axis so that there is no overlap of the ticks and bars on the x-axis?

1 Answer 1

25

There are a couple of things you can do. The full source code for the examples is at the bottom of this post. Note that you should always specify ymin=0 explicitly, otherwise the lowest data point will be used to determine the extent of the plot.

Make the plot wider: You could use the width and height options to make the plot wide enough to accommodate the x tick labels. To avoid the data labels from overlapping, you can rotate them using every node near coord/.append style={ anchor=mid west, rotate=70 }. In the example below, I've also switched off the upper and right axis borders using axis lines*=left (without the *, the axis lines would have arrow tips), so the rotated labels don't overlap the axis borders. Instead of this, you could also set enlarge y limits={upper,value=0.3} to enlarge the plot in positive y-direction by a factor of 1.3.

Rotate the x tick labels, round the data label values: If you want to keep the format unchanged, you could instead rotate the x tick labels using xticklabel style={ inner sep=0pt, anchor=north east, rotate=45 } (the inner sep and anchor options are needed to get the alignment right); decrease the width of the bars using bar width, and round the data labels to integers using nodes near coords={\pgfmathprintnumber[fixed,precision=0]{\pgfplotspointmeta}}.

Swap the axes: Or you could swap the x and y axes of your coordinates (this would be really simple if you would provide the data as a table, as you could then just redefine which column to use for x and y) and use xbar instead of ybar. This is probably the most sensible approach, as it allows a much better comparison of the values:


Rotated data labels, wide plot

\documentclass[a4paper]{article}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}% <-- moves axis labels near ticklabels (respects tick label widths)

\begin{document}

\begin{tikzpicture}
  \centering
  \begin{axis}[
        ybar,
    height=6cm,
    width=13cm,
    enlarge y limits=false,
    axis lines*=left,
    ymin=0,
    ymax=100,
     legend style={at={(0.5,-0.2)},
        anchor=north,legend columns=-1},
        ylabel={\#percentage},
        symbolic x coords={mod2,mod3,mod5,mod7,mod11,mod13,mod17,mod19,mod23},
     xtick=data,
        nodes near coords,
    every node near coord/.append style={
        anchor=mid west,
        rotate=70
    }
    ]
    \addplot coordinates {(mod2,75.4064) (mod3,89.7961) (mod5,94.4597)
      (mod7,96.6786) (mod11,97.5600) (mod13,98.2339)
      (mod17,98.6138) (mod19,98.9129) (mod23,99.0970)};
    \addplot coordinates {(mod2,30.5101) (mod3,34.5384) (mod5,36.3324)
      (mod7,37.3570) (mod11,37.9158) (mod13,38.3514)
      (mod17,38.6484) (mod19,38.9125) (mod23,39.1067)};
    \legend{Residue,non-Residue}
  \end{axis}
\end{tikzpicture}
\end{document}

Rotated x labels, node labels rounded to integers:

\documentclass[a4paper]{article}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{tikzpicture}
  \centering
  \begin{axis}[ybar,
    bar width=0.25cm,
    ymin=0,
    enlarge y limits={upper,value=0.15},
    legend style={at={(0.5,-0.25)},
    anchor=north,legend columns=-1},
    ylabel={\#percentage},
    symbolic x coords={mod2,mod3,mod5,mod7,mod11,mod13,mod17,mod19,mod23},
    xtick=data,
    xticklabel style={
        inner sep=0pt,
        anchor=north east,
        rotate=45
    },
    nodes near coords={\pgfmathprintnumber[fixed,precision=0]{\pgfplotspointmeta}},
    ]
    \addplot coordinates {(mod2,75.4064) (mod3,89.7961) (mod5,94.4597)
      (mod7,96.6786) (mod11,97.5600) (mod13,98.2339)
      (mod17,98.6138) (mod19,98.9129) (mod23,99.0970)};
    \addplot coordinates {(mod2,30.5101) (mod3,34.5384) (mod5,36.3324)
      (mod7,37.3570) (mod11,37.9158) (mod13,38.3514)
      (mod17,38.6484) (mod19,38.9125) (mod23,39.1067)};
    \legend{Residue,non-Residue}
  \end{axis}
\end{tikzpicture}

\end{document}

Swapped x and y axis:

\documentclass[a4paper]{article}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{tikzpicture}
  \centering
  \begin{axis}[
    xbar,
    bar width=0.2cm,
    legend style={at={(0.5,-0.15)},
    enlarge x limits={upper,value=0.19},
    xmin=0,xmax=100,
    anchor=north,legend columns=-1},
    ylabel={\#percentage},
    symbolic y coords={mod2,mod3,mod5,mod7,mod11,mod13,mod17,mod19,mod23},
    ytick=data,
    nodes near coords,
    nodes near coords align=horizontal,
    ]
    \addplot coordinates {(75.4064,mod2) (89.7961,mod3) (94.4597,mod5)
      (96.6786,mod7) (97.5600,mod11) (98.2339,mod13)
      (98.6138,mod17) (98.9129,mod19) (99.0970,mod23)};
    \addplot coordinates {(30.5101,mod2) (34.5384,mod3) (36.3324,mod5)
      (37.3570,mod7) (37.9158,mod11) (38.3514,mod13)
      (38.6484,mod17) (38.9125,mod19) (39.1067,mod23)};
    \legend{Residue,non-Residue}
  \end{axis}
\end{tikzpicture}

\end{document}
1
  • 1
    Thanks Jake for your very comprehensive answer. Much appreciated!
    – Bill
    Commented Sep 1, 2011 at 3:04

You must log in to answer this question.

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