시계열 데이터 플로팅

시계열 데이터 플로팅

특별한 x축 기능을 사용하여 분기별 시계열을 플롯하고 싶습니다. 특히, 분기가 시작되는 시기를 나타내는 작은 눈금과 연도의 시작 시기를 나타내는 큰 눈금을 보고 싶지만 분기가 아닌 연도에만 레이블을 지정하고 싶습니다. 설명을 위해 다음 예제에서는 코드가 전혀 유연하지 않다는 점을 제외하고 내가 원하는 작업을 정확하게 수행합니다.

\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} 

여러 가지 이유로 코드가 유연하지 않습니다. 예를 들어, 라고 쓰면 xtick={2009-01-01,2010-01-01,2011-01-01,2012-01-01,2013-01-01}minor x tick num=3작동을 멈춥니다(아마도 진드기의 거리가 같지 않기 때문일 것입니다). 또한 이 예에서는 수동으로 설정해야 합니다 xshift(예제에서 xshift=1.5cm). 코드가 분기별 시계열에 대해 모든 연도를 자동으로 표시할 수 있다면 좋을 것입니다. 또한 추가 x 틱 옵션을 사용하려고 시도했지만 성공하지 못했습니다.

스크린샷

답변1

이는 x coord trafo/.code및 에 대한 매우 좋은 습관임이 밝혀졌습니다 x coord inv trafo/.code. 그 전에 조금 설명을 드릴게요.

문제는 다음 세 부분으로 구성됩니다.

  • 첫째, 새해 전날마다 주요 진드기가 나타나야 합니다. 하지만 dateplot새해에 대해서는 아무것도 모릅니다.
  • 둘째, 작은 눈금은 큰 눈금이 균일하게 분리된 경우에만 나타납니다. 그러나 1년은 365일 또는 366일입니다.
  • 셋째, 레이아웃을 제어하고 싶습니다.

이를 극복하는 아주 쉬운 방법이 있습니다. 연도를 서로 같은 폭으로 만드는 것입니다. 보다 정확하게는 2015.09314를 사용하여 2015년 2월 3일 오늘을 나타냅니다. 이로 인해 모든 것이 변경됩니다.

  • 새해 전날은 이제 정수로 표시됩니다.pgfplots 사랑한다정수.
  • 연도는 1단위입니다.
  • 와 같은 것을 사용하면 레이아웃을 제어하는 ​​것이 더 쉽습니다 xmin=2008.

따라서 당신이 해야 할 일은 체크아웃 tikzlibrarypgfplots.dateplot.code.tex하고 직접 작성하는 것뿐입니다 year coordinates in. 다음 코드에서는 데이터를 플롯할 수 있도록 /pgfplots/#1 coord trafo입력을 2015-2-310진수로 변환하는 데 사용됩니다 . 반면에 는 10진수를 라벨 텍스트로 변환하는 데 사용됩니다. (대신 . ) (기본값이 충분하기 때문에 이 작업을 수행하지 않았습니다.) (음... 다른 구문에서는 아무것도 설정하지 않았습니다.)2015.09314pgfplotsx coord inv trafoMMXV20151000 sep

\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}

관련 정보