我想在 x 轴上按月/日比较几年的数据,只用刻度标签表示月份。我会称之为过度绘图吗?我的数据将包含每年的文件,格式为:年-月-日(2016-12-26)和一个值。每个文件都是前一年的。我使用图库中的一个例子作为起点,x 轴定义为:
\begin{axis}[date coordinates in=x, xticklabel={\day.\month.},
使用这个例子,多年的数据就如我预期的那样绘制出来了。
如何在同一轴上按月/日或仅按月绘制多年的数据?
我的第一个想法是将每个文件中的年份改为相同的值,但我觉得这会使我的数据集变得无用。有没有办法忽略日期条目的年份?一定有人遇到过这种情况。
谨致问候,戴夫。
答案1
据我了解,以下代码可以实现您的要求。我所做的是将原始数据读入表格,然后创建一个新列,其中年份是常数(我使用了 0 年,但您可以更改。)这与旧答案的第三个选项相同(见下文),但我对 xticks 做了一些修改。
\documentclass[border=5mm,tikz]{standalone}
% dummy data files
\usepackage{filecontents}
\begin{filecontents}{year1.dat}
t,y
2014-01-12,1
2014-02-12,2
2014-03-1,1
2014-03-10,1.2
2014-03-18,1.4
2014-04-12,3
2014-05-12,1.5
2014-06-12,1
2014-07-1,2
2014-07-12,2.5
2014-07-20,2.2
2014-08-12,1
2014-09-12,3
2014-10-12,1.5
2014-11-12,2.5
2014-12-12,2
\end{filecontents}
\begin{filecontents}{year2.dat}
t,y
2015-01-12,1.3
2015-02-12,2.4
2015-03-12,1.2
2015-04-12,3.5
2015-05-12,1.9
2015-06-12,1.2
2015-07-12,2.2
2015-08-12,1.4
2015-09-12,3.3
2015-10-12,1.8
2015-11-12,2.1
2015-12-12,2.2
\end{filecontents}
\usepackage{pgfplots,pgfplotstable}
\usepgfplotslibrary{dateplot}
% count for calculations
\newcount\julianday
% macro for reading files and adding column
% #1: filename
% #2: macroname to save table to
\newcommand\ReadFileYearZero[2]{%
\pgfplotstableread[col sep=comma]{#1}#2
\pgfplotstablecreatecol[
create col/assign/.code={
% convert the number of the current row and save it to `\julianday'
\pgfcalendardatetojulian{\thisrow{t}}{\julianday}
% convert to year-month-day
\pgfcalendarjuliantodate{\julianday}{\Year}{\Month}{\Day}
% make new entry in yearzero-column, with 0-<month>-<day>
\edef\entry{0-\Month-\Day}
\pgfkeyslet{/pgfplots/table/create col/next content}\entry
}
]{newday}{#2}}
% read in files - third option
\ReadFileYearZero{year1.dat}{\dataA}
\ReadFileYearZero{year2.dat}{\dataB}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
width=10cm,
height=6cm,
date coordinates in=x,
xlabel=Month,
xtick={ % ticks at first day of each month
0-1-1,
0-2-1,
0-3-1,
0-4-1,
0-5-1,
0-6-1,
0-7-1,
0-8-1,
0-9-1,
0-10-1,
0-11-1,
0-12-1},
xticklabel={\pgfcalendarmonthshortname{\month}}, % short name of month for ticklabels
xticklabel style={font=\footnotesize},
]
\addplot table [x=newday,y=y] {\dataA};
\addplot table [x=newday,y=y] {\dataB};
\addlegendentry{2014}
\addlegendentry{2015}
\end{axis}
\end{tikzpicture}
\end{document}
输出:
旧答案
下面的代码说明了三种不同的情况。我不太确定你的数据是什么样子的,但希望其中一种对你有用。这三种情况是:
假设每年每个月都有一个值,并且每年都是完整的,即数据文件中没有缺失的月份,那么这变得非常简单:
\addplot table [x expr=\coordindex+1,y=y,col sep=comma] {year1.dat};
x expr
用于计算 x 坐标。\coordindex
是数据点的计数,从零开始。因此,对于 12 个数据点,这变为 1,2,...,12。这也假设每个月一个值,但它从数据中提取月份数字,因此处理缺失的月份。
这会在数据表中创建一个新的日期列,其中年份设置为零。因此,这可能是最灵活的版本。
\documentclass[border=5mm,tikz]{standalone}
% dummy data files
\usepackage{filecontents}
\begin{filecontents}{year1.dat}
t,y
2014-01-12,1
2014-02-12,2
2014-03-12,1
2014-04-12,3
2014-05-12,1.5
2014-06-12,1
2014-07-12,2
2014-08-12,1
2014-09-12,3
2014-10-12,1.5
2014-11-12,2.5
2014-12-12,2
\end{filecontents}
\begin{filecontents}{year2.dat}
t,y
2015-01-12,1.3
2015-02-12,2.4
2015-03-12,1.2
2015-04-12,3.5
2015-05-12,1.9
2015-06-12,1.2
2015-07-12,2.2
2015-08-12,1.4
2015-09-12,3.3
2015-10-12,1.8
2015-11-12,2.1
2015-12-12,2.2
\end{filecontents}
\usepackage{pgfplots,pgfplotstable}
\usepgfplotslibrary{dateplot}
% count for calculations
\newcount\julianday
% for second option
% macro for reading files and adding column
% #1: filename
% #2: macroname to save table to
% note that the method is rather roundabout, and there
% are very likely better ways of achieving the same
\newcommand\ReadAndGetMonth[2]{%
\pgfplotstableread[col sep=comma]{#1}#2
\pgfplotstablecreatecol[
create col/assign/.code={
% convert the number of the current row and save it to `\julianday'
\pgfcalendardatetojulian{\thisrow{t}}{\julianday}
% convert to year-month-day
\pgfcalendarjuliantodate{\julianday}{\Year}{\Month}{\Day}
% save month value to new column
\edef\entry{\Month}
\pgfkeyslet{/pgfplots/table/create col/next content}\entry
}
]{month}{#2}}
% for third option
% macro for reading files and adding column
% #1: filename
% #2: macroname to save table to
\newcommand\ReadFileYearZero[2]{%
\pgfplotstableread[col sep=comma]{#1}#2
\pgfplotstablecreatecol[
create col/assign/.code={
% convert the number of the current row and save it to `\julianday'
\pgfcalendardatetojulian{\thisrow{t}}{\julianday}
% convert to year-month-day
\pgfcalendarjuliantodate{\julianday}{\Year}{\Month}{\Day}
% make new entry in yearzero-column, with 0-<month>-<day>
\edef\entry{0-\Month-\Day}
\pgfkeyslet{/pgfplots/table/create col/next content}\entry
}
]{newday}{#2}}
% read in files - second option
\ReadAndGetMonth{year1.dat}{\dataA}
\ReadAndGetMonth{year2.dat}{\dataB}
% read in files - third option
\ReadFileYearZero{year1.dat}{\dataAa}
\ReadFileYearZero{year2.dat}{\dataBb}
\begin{document}
% first option -- assuming one value per month, always
\begin{tikzpicture}
\begin{axis}[
width=10cm,
height=6cm,
xlabel=Month,
xtick=data,
xticklabel={\pgfcalendarmonthshortname{\tick}}, % 1-> Jan, etc.
xticklabel style={font=\footnotesize},
]
% \coordindex starts counting from 0
\addplot table [x expr=\coordindex+1,y=y,col sep=comma] {year1.dat};
\addplot table [x expr=\coordindex+1,y=y,col sep=comma] {year2.dat};
\addlegendentry{2014}
\addlegendentry{2015}
\end{axis}
\end{tikzpicture}
% second option - month alone
\begin{tikzpicture}
\begin{axis}[
width=10cm,
height=6cm,
xlabel=Month,
xtick={1,...,12},
xticklabel={\pgfcalendarmonthshortname{\tick}},
xticklabel style={font=\footnotesize},
]
\addplot table [x=month,y=y] {\dataA};
\addplot table [x=month,y=y] {\dataB};
\addlegendentry{2014}
\addlegendentry{2015}
\end{axis}
\end{tikzpicture}
% third option - month and day in year 0
\begin{tikzpicture}
\begin{axis}[
width=10cm,
height=6cm,
date coordinates in=x,
xlabel=Month,
% xtick={ % if you wish to set cticks at specific dates
% 0-1-12, % year-month-day
% 0-2-12,
% 0-3-12,
% 0-4-12,
% 0-5-12,
% 0-6-12,
% 0-7-12,
% 0-8-12,
% 0-9-12,
% 0-10-12,
% 0-11-12,
% 0-12-12},
xticklabel={\day.\month},
xticklabel style={font=\footnotesize},
]
\addplot table [x=newday,y=y] {\dataAa};
\addplot table [x=newday,y=y] {\dataBb};
\addlegendentry{2014}
\addlegendentry{2015}
\end{axis}
\end{tikzpicture}
\end{document}