0

I have a dataset in which rows indicate years and columns firms. For each year, I want to plot the 1st firm's rank against the others.

In the example below, 2013 is tied for 5th (if this is too tricky, I can break the rounding) as cells 1 to 8 (ex. cell 0) in the 2013 row are ordered: 0.67 (F3; 1st) > 0.54 (F6; 2nd) > 0.48 (F2; 3rd) > 0.46 (F8; 4th) > 0.38 (F1 & F4; joint 5th). In years 2014 onwards, F1 is ranked 6th.

\documentclass{article}
\usepackage{pgfplotstable}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\pgfplotstableread[col sep=tab,row sep=\\,header=false]{
  % year    F1      F2      F3      F4      F5      F6      F7      F8
  2013  0.38    0.48    0.67    0.38    0.34    0.54    0.32    0.46 \\
  2014  0.37    0.48    0.70    0.39    0.34    0.54    0.31    0.50 \\
  2015  0.35    0.44    0.68    0.38    0.30    0.53    0.28    0.49 \\
  2016  0.33    0.43    0.67    0.35    0.29    0.51    0.29    0.47 \\
}\datatable

\begin{tikzpicture}
  \begin{axis}[
    ylabel = rank, y dir = reverse,
  ]

  \addplot table [x expr=\coordindex, y expr= % what goes here? 
    ] {\datatable};

  \end{axis}
\end{tikzpicture}

\end{document}

A hand-coded version of the result I want is below.

hand-coded graph

2
  • 1
    For me it is still unclear how the resulting plot should look like. Could you add a sketch of the result. Then I think we will be able to provide a solution without multiple iterations because the question is "unclear". Mar 7, 2019 at 6:13
  • Thanks Stefan. I've added a plot and tried to clarify the text. Mar 7, 2019 at 8:32

1 Answer 1

2

So you are searching for something like the following? Hopefully this is self-explanatory ...

% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{pgfplotstable}
    \pgfplotsset{
        compat=1.3,
        /pgf/declare function={
            MyRank(\a,\b,\c,\d,\e,\f,\g,\h) =
                ifthenelse( \a == min(\a,\b,\c,\d,\e,\f,\g,\h), 1,
                ifthenelse( \b == min(\a,\b,\c,\d,\e,\f,\g,\h), 2,
                ifthenelse( \c == min(\a,\b,\c,\d,\e,\f,\g,\h), 3,
                ifthenelse( \d == min(\a,\b,\c,\d,\e,\f,\g,\h), 4,
                ifthenelse( \e == min(\a,\b,\c,\d,\e,\f,\g,\h), 5,
                ifthenelse( \f == min(\a,\b,\c,\d,\e,\f,\g,\h), 6,
                ifthenelse( \g == min(\a,\b,\c,\d,\e,\f,\g,\h), 7,
                8)))))));
        },
    }
    % (please note that I have changed the first value of F5)
    \pgfplotstableread{
        year    F1      F2      F3      F4      F5      F6      F7      F8
        2013  0.38    0.48    0.67    0.38    0.30    0.54    0.32    0.46
        2014  0.37    0.48    0.70    0.39    0.34    0.54    0.31    0.50
        2015  0.35    0.44    0.68    0.38    0.30    0.53    0.28    0.49
        2016  0.33    0.43    0.67    0.35    0.29    0.51    0.29    0.47
    }\datatable
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        ylabel=rank,
        y dir=reverse,
        xtick distance=1,
        ytick distance=1,
    ]
        \addplot table [
            x expr=\coordindex,
            y expr={
                MyRank(
                    \thisrow{F1},
                    \thisrow{F2},
                    \thisrow{F3},
                    \thisrow{F4},
                    \thisrow{F5},
                    \thisrow{F6},
                    \thisrow{F7},
                    \thisrow{F8}
                )
            }
        ] {\datatable};
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

7
  • Thank you Stefan. Is there an easy way of extending this beyond nine columns? (My non-minimal problem has over 20.) Mar 8, 2019 at 13:07
  • 1
    Unfortunately I don't have an idea ... Mar 8, 2019 at 15:02
  • Hi Stefan - I've just taken a closer look at the above: it seems to return arg min, rather than returning the rank of the F1 column. I've tried to extend the ifthenelse structure, but get nests on both sides on the conditional statements, so am not sure that this is an efficient way forward. I wonder if a recursive approach makes more sense. Mar 12, 2019 at 16:13
  • That is true. But pgfplots does not have a rank function included, the same holds for gnuplot (as far as I know). I think that it would be much easier to determine the rank in an external program (like Excel), save the result in another table and plot this one ... Mar 12, 2019 at 16:30
  • Thanks Stefan. I've wondered how pointless it is to try to do this in PGF. I'm sticking at it so far as I've got one underlying dataset from which I want to generate a number of plots. From a maintenance point of view, I liked the idea of just running a bunch of PGF scripts on that one dataset. Mar 15, 2019 at 12:30

You must log in to answer this question.

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