![pgfplots 数据时间格式中的刻度标签](https://linux22.com/image/280914/pgfplots%20%E6%95%B0%E6%8D%AE%E6%97%B6%E9%97%B4%E6%A0%BC%E5%BC%8F%E4%B8%AD%E7%9A%84%E5%88%BB%E5%BA%A6%E6%A0%87%E7%AD%BE.png)
我尝试使用 pgfplots 绘制包含秒和毫秒的数据集。我在这里找到了我的任务的解决方案(pgfplots 数据时间格式),我做了一些修改。这基本上很有效。我的代码如下:
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{dateplot}
\def\transformtime#1:#2:#3!{
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\pgfmathparse{#1*3600-\pgfkeysvalueof{/pgfplots/timeplot zero}*3600+#2*60+#3}
\pgfkeys{/pgf/fpu=false}
}
\pgfplotsset{
timeplot zero/.initial=0,
timeplot/.style={
y coord trafo/.code={\expandafter\transformtime##1!},
y coord inv trafo/.code={%
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed,}
\pgfmathsetmacro\hours{floor(##1/3600)+\pgfkeysvalueof{/pgfplots/timeplot zero}}
\pgfmathsetmacro\minutes{floor((##1-(\hours - \pgfkeysvalueof{/pgfplots/timeplot zero})*3600)/60)}
\pgfmathsetmacro\seconds{##1-floor((##1)/60)*60}
\def\pgfmathresult{\pgfmathprintnumber{\hours}:\pgfmathprintnumber{\minutes}:\pgfmathprintnumber[fixed zerofill]{\seconds}}
\pgfkeys{/pgf/fpu=false}
},
scaled y ticks=false,
yticklabel=\tick
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
timeplot, timeplot zero=0, grid=major, grid style=dashed, ytick={00:12:00, 00:13:00, 00:14:00},
]
\addplot table {
State Time
-13 00:12:42.40
-12 00:12:57.06
-11 00:13:17.59
-10 00:13:40.83
-9 00:14:07.44
-8 00:14:31.11
-7 00:14:04.28
-6 00:14:12.07
-5 00:14:09.27
-4 00:13:59.92
-3 00:13:56.82
-2 00:13:55.17
-1 00:13:53.52
0 00:13:52.47
1 00:13:59.32
2 00:14:00.58
3 00:13:43.12
4 00:13:49.05
5 00:13:28.63
};
\end{axis}
\end{tikzpicture}
\end{document}
现在的问题是我得到了奇怪的刻度标签(12:60 和 14:0.00 都不是我想要的......):
我发现了一个类似的问题(使用带有奇数刻度标签的 pgfplots 绘制日期图),但不幸的是,我不知道如何通过该解决方案解决我的问题。这里有人可以给我提示吗?
答案1
这是一次尝试,我添加了一些条件代码,当数字小于 10 时添加前导零。想法是这样的(对于分钟部分):
\pgfmathparse{ifthenelse(\minutes<10,0,)}\pgfmathresult\pgfmathprintnumber{\minutes}:%
根据是否需要前导零(通过测试是否小于 10 来确定),将存储 或空字符串。然后通过调用组内的内容将其转储到顶层\pgfmathparse
的中,然后是分钟数本身的 。0
\minutes
\def
\pgfmathresult
\pgfmathresult
\pgfmathprintnumber
不幸的是,我没能真正解决12:60
舍入问题。我认为从下往上而不是从上往下定义、 和可能会有所帮助,但这会在其他方面引起问题\seconds
。\minutes
\hours
但是:禁用 FPU 可以使其正确,不会产生任何不利影响,因为pgfplots
它会自行缩放以避免“尺寸太大”错误。因此,对于您来说,这可能是也可能不是一个可以接受的解决方案。
我还更改了打印选项\seconds
:
\pgfmathprintnumber[fixed,fixed zerofill]{\seconds}%
添加fixed
“锁定”固定模式,这样科学计数法就永远不会被使用,而且总是fixed zerofill
会受到尊重(因为我们总是处于fixed
模式)。
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\usepgfplotslibrary{dateplot}
\def\transformtime#1:#2:#3!{
% \pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\pgfmathparse{#1*3600-\pgfkeysvalueof{/pgfplots/timeplot zero}*3600+#2*60+#3}
% \pgfkeys{/pgf/fpu=false}
}
\pgfplotsset{
timeplot zero/.initial=0,
timeplot/.style={
y coord trafo/.code={\expandafter\transformtime##1!},
y coord inv trafo/.code={%
% \pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed,}
\pgfmathsetmacro\hours{floor(##1/3600)+\pgfkeysvalueof{/pgfplots/timeplot zero}}
\pgfmathsetmacro\minutes{floor((##1-(\hours - \pgfkeysvalueof{/pgfplots/timeplot zero})*3600)/60)}
\pgfmathsetmacro\seconds{##1-floor((##1)/60)*60}
\def\pgfmathresult{%
\pgfmathparse{ifthenelse( \hours<10,0,)}\pgfmathresult\pgfmathprintnumber{\hours}:%
\pgfmathparse{ifthenelse(\minutes<10,0,)}\pgfmathresult\pgfmathprintnumber{\minutes}:%
\pgfmathparse{ifthenelse(\seconds<10,0,)}\pgfmathresult\pgfmathprintnumber[fixed,fixed zerofill]{\seconds}%
}
% \pgfkeys{/pgf/fpu=false}
},
scaled y ticks=false,
yticklabel=\tick
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
timeplot, timeplot zero=0, ytick={00:11:30.056, 00:12:00, 00:13:00, 00:14:00},
]
\addplot table {
State Time
-13 00:12:42.40
-12 00:12:57.06
-11 00:13:17.59
-10 00:13:40.83
-9 00:14:07.44
-8 00:14:31.11
-7 00:14:04.28
-6 00:14:12.07
-5 00:14:09.27
-4 00:13:59.92
-3 00:13:56.82
-2 00:13:55.17
-1 00:13:53.52
0 00:13:52.47
1 00:13:59.32
2 00:14:00.58
3 00:13:43.12
4 00:13:49.05
5 00:13:28.63
7 00:11:15.6256432
};
\end{axis}
\end{tikzpicture}
\end{document}