Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am making an xbar plot with pgfplots. I want this plot to show the results from a test, where people in different age classes are given scores. For each of these age classes a single person is the winner. See the attached latex file containing the dataset "data.dat", with four columns: Age-interval, Y-position, Score, and Name.

I want my xbar plot to have different y tick labels on, respectively, the left and the right side y axes. The left side y tick labels denotes the age intervals of the persons tested (20-30, 30-40,...), while the right side y tick labels should denote the winner in each of the age intervals (Peter, Jeff, ...).

Two questions:

(1) I am not able to make a left side and a right side set of y tick labels simultaneously. How can I do that?

Adding two extra lines of code, for showing right side y tick labels (code block starting with "% (2) "), does not solve my problem, only shifting it from showing only the left side y tick labels to showing only the right side y tick labels

(2) How do I prevent the plot title to overlap with the x tick labels?

here is my code:

{\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=1.3}

% test scores and person names
\begin{filecontents}{data.dat}
Age-interval        Y-Position         Score        Name
20-30               1                  15           Peter
30-40               2                  20           Jeff
40-50               3                  12           Steve
50-60               4                  24           John 
\end{filecontents}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
    title = {Test score},
    xbar,     
    bar width=2pt,
    ytick=data,
    width=8 cm,
    height=5 cm,
    xmin=-1,
    xmax = 100,
    xticklabel pos = upper,
    tick align = outside,
    %
    % (1) add left side y tick labels
    yticklabel pos=left, 
    yticklabels from table={data.dat}{Age-interval},
    %
    % (2) add righ side y tick labels
    %    yticklabel pos=right, 
    %    yticklabels from table={data.dat}{Name},
    %
    ylabel={Age intervals (yr)},
]
\addplot table [
    y=Y-Position,
    x=Score, 
] {data.dat};
\end{axis}

\end{tikzpicture}
\end{document}
share|improve this question
add comment

2 Answers

Instead of using the title key, I would use xlabel, since that's what you're trying to get and it gets the position right (the fact that the title overlaps the labels is a bug though, I'll file a report).

For printing the names on the right-hand side of the axis, you could use extra y ticks, with every extra y tick/.style={yticklabel pos=right, yticklabels from table={data.dat}{Name}}.

A different approach would be to use nodes near coords to place the names near the bars. For this, you have to set point meta=explicit symbolic in the axis to tell pgfplots not to use the x value for the labels (explicit) and to switch off the number parser for the meta data (symbolic), and meta=Names in the \addplot table options. To position the labels to the right of the bars, you can use every node near coord/.append style={anchor=west}.


Labels on right side of plot

\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=newest}

\begin{filecontents}{data.dat}
Age-interval        Y-Position         Score        Name
20-30               1                  15           Peter
30-40               2                  20           Jeff
40-50               3                  12           Steve
50-60               4                  24           John 
\end{filecontents}

\begin{document}
\begin{tikzpicture}

\makeatletter
\begin{axis}[
    xlabel={Test score},
    xbar,     
    bar width=2pt,
    ytick=data,
    width=8 cm,
    height=5 cm,
    xmin=-1,
    xmax = 100,
    xticklabel pos = upper,
    tick align = outside,
    yticklabel pos=left, 
    yticklabels from table={data.dat}{Age-interval},
    ylabel={Age intervals (yr)},
    extra y ticks={1,...,4},
    every extra y tick/.style={
        yticklabel pos=right,
        yticklabels from table={data.dat}{Name}}
]
\addplot table [
    y=Y-Position,
    x=Score
] {data.dat};
\end{axis}

\end{tikzpicture}
\end{document}

Labels near bars

\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=newest}

\begin{filecontents}{data.dat}
Age-interval        Y-Position         Score        Name
20-30               1                  15           Peter
30-40               2                  20           Jeff
40-50               3                  12           Steve
50-60               4                  24           John 
\end{filecontents}

\begin{document}
\begin{tikzpicture}

\makeatletter
\begin{axis}[
    xlabel={Test score},
    xbar,     
    bar width=2pt,
    ytick=data,
    width=8 cm,
    height=5 cm,
    xmin=-1,
    xmax = 100,
    xticklabel pos = upper,
    tick align = outside,
    yticklabel pos=left, 
    yticklabels from table={data.dat}{Age-interval},
    ylabel={Age intervals (yr)},
    nodes near coords,
    every node near coord/.append style={anchor=west},
    point meta=explicit symbolic
]
\addplot table [
    y=Y-Position,
    x=Score,
    meta=Name
] {data.dat};
\end{axis}

\end{tikzpicture}
\end{document}
share|improve this answer
    
Thans a lot Jake! I have a follow-up question regarding your code in "Labels on right side of plot". You are defining "extra y ticks={1,...,4}," because the original y ticks consisted of {1,2,3,4}. But if the original data shfts, having y ticks = {1,2,3,4,5}, then I will have to change your code to "extra y ticks={1,...,4,5},". How could "extra y ticks" be adjusted automatically to fit the values in "y ticks"? –  Espen Donali Feb 1 '12 at 12:02
add comment

Your first problem can be solved by using a second axis with the option yticklabel pos = right to get the other y-labels on the right side.

Your second problem - the overlapping of title and x tick labels - can be addressed by shifting the title upwards using the option title style = {yshift=<length>}.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=1.3}

% test scores and person names
\begin{filecontents}{data.dat}
Age-interval        Y-Position         Score        Name
20-30               1                  15           Peter
30-40               2                  20           Jeff
40-50               3                  12           Steve
50-60               4                  24           John 
\end{filecontents}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
    title = {Test score},
    title style = {yshift = 10pt},
    xbar,     
    bar width=2pt,
    ytick=data,
    width=8 cm,
    height=5 cm,
    xmin=-1,
    xmax = 100,
    xticklabel pos = upper,
    tick align = outside,
    yticklabel pos=left, 
    yticklabels from table={data.dat}{Age-interval},
    ylabel={Age intervals (yr)},
]
\addplot table [
    y=Y-Position,
    x=Score, 
] {data.dat};
\end{axis}
\begin{axis}[
    xbar,     
    bar width=2pt,
    ytick=data,
    width=8 cm,
    height=5 cm,
    xmin=-1,
    xmax = 100,
    xticklabels = none,
    tick align = outside,
    yticklabel pos=right, 
    yticklabels from table={data.dat}{Name},
    ylabel={Winner},
]
\addplot table [
    y=Y-Position,
    x=Score, 
] {data.dat};
\end{axis}


\end{tikzpicture}
\end{document}
share|improve this answer
    
Thanks a lot! That solved a lot of problems:) My own solution, which did not work, is close to yours with an extra axis environment, but I did not include an extra \addplot line. Why do I have to have an \addplot line in each of the two axis environments? It seems like waste of code to plot the same data twice? –  Espen Donali Jan 31 '12 at 15:16
    
@EspenDonali: I was a bit in a hurry and couldn't figure out how to get the y tick labels for the y axis on the right positioned automatically without repeating the plot. But you're right, plotting data twice is a waste of resources. If you have a solution that avoids this I'd be grateful if you could post it. –  Philipp Jan 31 '12 at 20:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.