我有一个 pgfplot,其中包含 x 的日期和 y 的一些值,现在我想为其添加一条平均线,就像这样这里。但是,我怀疑那里介绍的函数\DrawHMean
似乎在日期方面存在问题。不幸的是,一个简单的函数也不起作用。我该怎么做才能将(已经计算好的!)平均值放入图表中?\pgfkeysvalueof{/pgfplots/xmin}
…xmax}
\addplot expression {y=\Mean}
平均能量损失
负责绘制平均线的注释行在激活时会产生与日期相关的错误。
\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.9}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
value date
1.84919 2017-04-09
0.97280 2017-04-10
4.78586 2017-04-11
3.95797 2017-04-12
4.50753 2017-04-13
2.52274 2017-04-14
5.13984 2017-04-15
0.29474 2017-04-16
5.39946 2017-04-17
4.40204 2017-04-18
\end{filecontents*}
\newcommand\DrawHMean[1][]{
\draw[#1]
(axis cs:\pgfkeysvalueof{/pgfplots/xmin},\Mean) --
(axis cs:\pgfkeysvalueof{/pgfplots/xmax},\Mean);
}
\newcommand\GetMean[2]{
\pgfplotstableread{#1}\tableA
\pgfplotstableset{
create on use/new/.style={
create col/expr={\pgfmathaccuma + \thisrow{#2}}},
}
\pgfplotstablegetrowsof{\tableA}
\pgfmathsetmacro{\NumRows}{\pgfplotsretval}
\pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1}
\pgfmathsetmacro{\Sum}{\pgfplotsretval}
\pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}
\begin{document}
\begin{tikzpicture}
\GetMean{data.csv}{value}
\begin{axis}[%
date coordinates in=x,%
xticklabel style={rotate=90,anchor=near xticklabel},%
xticklabel=\day.\month.\year,%
]
\addplot[red] table [x=date, y=value] {data.csv};
% \DrawHMean[blue, ultra thick, dashed]
\end{axis}
\end{tikzpicture}
\end{document}
输出
谢谢你的帮助!
答案1
您可以搜索表中给出的第一个日期
\newcommand\FirstDate{}
\newcommand\GetFirstDate[2]{%
\pgfplotstablegetelem{0}{#2}\of{#1}%
\edef\FirstDate{\pgfplotsretval}%
}
并使用它
\newcommand\DrawHMean[2][]{%
\draw[#1]
({axis cs:\FirstDate,\Mean}-|current axis.west) --
({axis cs:\FirstDate,\Mean}-|current axis.east);%
}
代码:
\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.9}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
value date
1.84919 2017-04-09
0.97280 2017-04-10
4.78586 2017-04-11
3.95797 2017-04-12
4.50753 2017-04-13
2.52274 2017-04-14
5.13984 2017-04-15
0.29474 2017-04-16
5.39946 2017-04-17
4.40204 2017-04-18
\end{filecontents*}
\newcommand\DrawHMean[2][]{%
\draw[#1]
({axis cs:\FirstDate,\Mean}-|current axis.west) --
({axis cs:\FirstDate,\Mean}-|current axis.east);%
}
\newcommand\FirstDate{}
\newcommand\GetFirstDate[2]{%
\pgfplotstablegetelem{0}{#2}\of{#1}%
\edef\FirstDate{\pgfplotsretval}%
}
\newcommand\GetMean[2]{
\pgfplotstableread{#1}\tableA
\pgfplotstableset{
create on use/new/.style={
create col/expr={\pgfmathaccuma + \thisrow{#2}}},
}
\pgfplotstablegetrowsof{\tableA}
\pgfmathsetmacro{\NumRows}{\pgfplotsretval}
\pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1}
\pgfmathsetmacro{\Sum}{\pgfplotsretval}
\pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}
\begin{document}
\begin{tikzpicture}
\GetFirstDate{data.csv}{date}
\GetMean{data.csv}{value}
\begin{axis}[clip=false,%
date coordinates in=x,%
xticklabel style={rotate=90,anchor=near xticklabel},%
xticklabel=\day.\month.\year,%
]
\addplot[red] table [x=date, y=value] {data.csv};
\DrawHMean[blue, ultra thick, dashed]{data.csv}
\end{axis}
\end{tikzpicture}
\end{document}
答案2
我在添加的轴选项中发现了一个使用内部函数的更简单的解决方案:
extra y ticks=\Mean,
extra y tick style={thick,blue,grid=major,grid style={thick,blue,dashed}},
extra y tick label={mean = $\pgfmathprintnumber\tick$},
这将\Mean
(当然仍需在之前计算\GetMean
)设置为 y 轴上的额外刻度。整个示例如下所示:
\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.9}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
value date
1.84919 2017-04-09
0.97280 2017-04-10
4.78586 2017-04-11
3.95797 2017-04-12
4.50753 2017-04-13
2.52274 2017-04-14
5.13984 2017-04-15
0.29474 2017-04-16
5.39946 2017-04-17
4.40204 2017-04-18
\end{filecontents*}
\newcommand\GetMean[2]{
\pgfplotstableread{#1}\tableA
\pgfplotstableset{
create on use/new/.style={
create col/expr={\pgfmathaccuma + \thisrow{#2}}},
}
\pgfplotstablegetrowsof{\tableA}
\pgfmathsetmacro{\NumRows}{\pgfplotsretval}
\pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1}
\pgfmathsetmacro{\Sum}{\pgfplotsretval}
\pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}
\begin{document}
\begin{tikzpicture}
\GetMean{data.csv}{value}
\begin{axis}[%
date coordinates in=x,%
xticklabel style={rotate=90,anchor=near xticklabel},%
xticklabel=\day.\month.\year,%
extra y ticks=\Mean,
extra y tick style={thick,blue,grid=major,grid style={thick,blue,dashed}},% style options
extra y tick label={mean = $\pgfmathprintnumber\tick$},% label text, change to {} for empty label
]
\addplot[red] table [x=date, y=value] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}
我保留 esdd 的答案作为接受的答案,因为它回答了我的确切问题,但我认为这种方法可以更好地解决如何向 pgfplot 添加自动计算的平均线的总体问题。