Zeitreihendaten grafisch darstellen

Zeitreihendaten grafisch darstellen

Ich möchte vierteljährliche Zeitreihen mit speziellen X-Achsen-Funktionen darstellen. Insbesondere möchte ich kleine Markierungen sehen, die anzeigen, wann die Quartale beginnen, und größere Markierungen, die anzeigen, wann die Jahre beginnen, möchte aber nur die Jahre (und nicht die Quartale) beschriften. Zur Veranschaulichung macht das folgende Beispiel genau das, was ich möchte, außer dass der Code überhaupt nicht flexibel ist.

\documentclass{article}   
\usepackage{pgfplots}   
\usepackage{filecontents}
\pgfplotsset{width=8cm,compat=newest}   
\usepgfplotslibrary{dateplot}     

\usetikzlibrary{calc}

\begin{filecontents}{Quarterly.dat}
date    Y
2009-02-15  1
2009-05-15  2
2009-08-15  3
2009-11-15  4
2010-02-15  4
2010-05-15  4
2010-08-15  4
2010-11-15  4
2011-02-15  4
2011-05-15  4
2011-08-15  4
2011-11-15  4
2012-02-15  4
2012-05-15  4
2012-08-15  4
2012-11-15  4
2013-02-15  4
2013-05-15  4
2013-08-15  4
2013-11-15  4
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
mark =none,
xmin=2008-12-01,
xmax=2012-02-01,
major tick length=4pt,
minor tick length=2pt,
date coordinates in=x,
minor x tick num=3,
xtick={2009-01-01,2010-01-01,2011-01-01,2012-01-01}, 
xticklabels= {\year,\year,\year},
x tick label style={anchor=east,xshift=1.5cm,yshift=-0.3cm},
]
\addplot [only marks,green]table [x=date,y=Y]{Quarterly.dat}; %
\end{axis}
\end{tikzpicture}
\end{document} 

Der Code ist aus mehreren Gründen nicht flexibel. Wenn ich beispielsweise schreibe xtick={2009-01-01,2010-01-01,2011-01-01,2012-01-01,2013-01-01}, minor x tick num=3funktioniert das nicht mehr (wahrscheinlich, weil die Ticks nicht den gleichen Abstand haben). Das Beispiel erfordert auch, dass ich manuell einstellen muss xshift(im Beispiel xshift=1.5cm). Es wäre toll, wenn der Code alle Jahre für jede vierteljährliche Zeitreihe automatisch beschriften könnte. Ich habe auch versucht, die Option für zusätzliche x Ticks zu verwenden, aber ohne Erfolg.

Bildschirmfoto

Antwort1

Es stellt sich heraus, dass dies eine sehr gute Vorgehensweise für x coord trafo/.codeund ist x coord inv trafo/.code. Lassen Sie mich vorher etwas erklären.

Ihr Problem gliedert sich in die folgenden drei Teile:

  • Erstens sollten an jedem Silvester große Häkchen erscheinen. Aber dateplotman weiß nichts über Neujahr.
  • Zweitens erscheinen kleine Teilstriche nur, wenn große Teilstriche gleichmäßig voneinander getrennt sind. Jahre sind jedoch 365 oder 366 Tage lang.
  • Drittens möchten Sie das Layout steuern.

Es gibt eine sehr einfache Möglichkeit, das zu umgehen: Machen Sie die Jahre gleich breit. Genauer gesagt verwende ich 2015.09314, um den heutigen Tag, den 3. Februar 2015, darzustellen. Das ändert alles, weil:

  • Silvester werden nun durch ganze Zahlen dargestellt undpgfplots LIEBTganze Zahl.
  • Jahre sind eine Einheit lang.
  • Die Steuerung des Layouts ist mit etwas wie einfacher xmin=2008.

Sie müssen also nur nachsehen tikzlibrarypgfplots.dateplot.code.texund Ihr eigenes schreiben year coordinates in. Im folgenden Code /pgfplots/#1 coord trafowird verwendet, um Ihre Eingabe 2015-2-3in eine Dezimalzahl umzuwandeln 2015.09314, damit pgfplotsSie die Daten darstellen können. Andererseits x coord inv trafowird verwendet, um die Dezimalzahl in einen Beschriftungstext umzuwandeln. (Zum Beispiel MMXVanstelle von 2015.) (Das habe ich nicht gemacht, weil die Vorgabe gut genug ist.) (Nun... ich habe 1000 sepin einer anderen Syntax nichts eingestellt.)

\documentclass[border=1cm]{standalone}
\usepackage{pgfplots}
    \usepgfplotslibrary{dateplot}
\begin{filecontents}{\jobname-Quarterly.dat}
date Y
2009-01-01 9
2009-12-31 9
2010-01-01 0
2010-12-31 0
2014-01-01 4
2014-12-31 4
\end{filecontents}

\makeatletter
\pgfplotsset{
    /pgfplots/year coordinates in/.code={
        \pgfkeysalso{%
            #1 tick label style={/pgf/number format/1000 sep=}, % "2015" rather than "2,015"
            #1 tick label as interval,
            minor #1 tick num=11 % January, ..., December
        }
        \pgfkeysdef{/pgfplots/#1 coord trafo}{
            \begingroup
            \edef\pgfplotstempjuliandate{##1}
            % check if we also have a TIME like '2006-01-01 11:21'
            \expandafter\pgfutil@in@\expandafter:\expandafter{\pgfplotstempjuliandate}
            \ifpgfutil@in@
                % we have a TIME!
                \expandafter\pgfplotslibdateplot@map@time\pgfplotstempjuliandate:\dateto\pgfplotstempjuliandate\timeto\pgfplotstemptime
            \else
                \let\pgfplotstemptime=\pgfutil@empty
            \fi
            \expandafter\pgfcalendardatetojulian\expandafter{\pgfplotstempjuliandate}\c@pgf@counta
            \expandafter\pgfcalendardatetojulian\expandafter{\year-1-0}\c@pgf@countb
            \expandafter\pgfcalendardatetojulian\expandafter{\year-12-31}\c@pgf@countc
            \advance\c@pgf@counta by-\c@pgf@countb % now a = #days from 1/1 to temp
            \advance\c@pgf@countc by-\c@pgf@countb % now b = #days of that year
            \ifx\pgfplotstemptime\pgfutil@empty
                % no time:
                \pgfmathparse{\year+\the\c@pgf@counta/\the\c@pgf@countc}
            \else
                % add time fraction (which should be in the range
                % [0,1]).
                \ifdim\pgfplotstemptime pt<1pt
                    % discard prefix '0.':
                    \expandafter\pgfplotslibdateplot@discard@zero@dot\pgfplotstemptime\to\pgfplotstemptime
                    \pgfmathparse{\year+(\the\c@pgf@counta.\pgfplotstemptime)/\the\c@pgf@countc}%
                \else
                    % assume \pgfplotstemptime=1pt :
                    \advance\c@pgf@counta by1
                    \pgfmathparse{\year+\the\c@pgf@counta/\the\c@pgf@countc}
                \fi
            \fi
            \pgfmath@smuggleone\pgfmathresult
            \endgroup
        }
    }
}

\begin{document}
    \begin{tikzpicture}
        \begin{axis}[year coordinates in=x,minor x tick num=1]
            \addplot [only marks]table[x=date,y=Y]{\jobname-Quarterly.dat};
        \end{axis}
    \end{tikzpicture}
\end{document}

verwandte Informationen