繪製時間序列數據

繪製時間序列數據

我想繪製具有特殊 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對新年一無所知。
  • 其次,只有當主要蜱蟲均勻分開時,才會出現次要蜱蟲。但一年有 365 或 366 天長。
  • 第三,你想要控制佈局。

有一個非常簡單的方法可以克服這個問題:讓年份彼此一樣寬。更準確地說,我使用 2015.09314 代表今天,即 2015 年 2 月 3 日。

  • 除夕夜現在用整數表示pgfplots 整數。
  • 年是一個單位長。
  • 使用諸如 之類的東西控制佈局更容易xmin=2008

因此,您所要做的就是檢查tikzlibrarypgfplots.dateplot.code.tex並編寫自己的year coordinates in.在以下程式碼中,/pgfplots/#1 coord trafo用於將輸入轉換2015-2-3為十進制數2015.09314,以便pgfplots可以繪製資料。另一方面,x coord inv trafo用於將十進制數轉換為標籤文字。 (例如,MMXV而不是2015。)(我沒有這樣做,因為預設值已經足夠好了。)(嗯......我1000 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}

相關內容