我有一个数据集,其中包含随时间重复发生的事件。每个事件都会花费任意长的时间。我可以使用绘制此图,gnuplot
但由于脚本的黑客性质,我无法生成正确的键。我不得不手动绘制图例。图如下所示:
我可以通过 TikZ 或其他绘图工具做这样的事情吗?
我的数据集如下:
running 20
stage-out 47
running 34
stage-in 3
running 24
stage-out 39
...
如上所示,该文件是两列文本,其中第一列表示事件名称,第二列表示该事件的时间间隔。
答案1
在我所有失败的尝试之后(已删除)我有一个版本可以工作。
问题是,在axis
环境内部,循环\DTLforeach
没有在适当的时刻展开宏,而是在循环结束后展开。这导致只绘制了一个(即最后一个)框。
\eappto
此解决方案避免了这个问题,因为它在 ( )之前组装了所有的 TikZ 命令,但\draw
或\fill
不能扩展,这就是它前面有的原因\noexpand
。
解决方案 1
该解决方案pgfplots
仅使用轴,框由绘制TikZ
。
代码
\documentclass{article}
\usepackage[separator={{ }}]{datatool}% loads etoolbox
\usepackage{pgfplots}
\def\maximum{0}
\def\whattodraw{}
\begin{filecontents}{dataset.dat}
running 20
stage-out 47
running 34
stage-in 3
running 24
stage-out 39
\end{filecontents}
\begin{filecontents}{datasetcolor.dat}
stage-in red!75
stage-out green
running orange
\end{filecontents}
\DTLloaddb[noheader,keys={name,value},headers={name,value}]{dataset}{dataset.dat}
\DTLloaddb[noheader,keys={namec,color},headers={namec,color}]{datasetcolor}{datasetcolor.dat}
\DTLforeach*{datasetcolor}{\name=namec,\tikzColor=color}{
\tikzset{DSCOLOR\name/.estyle={fill=\tikzColor}}
}
\DTLforeach{dataset}{\name=name,\val=value}{
\DTLappendtorow{cumval}{\maximum}
\pgfmathsetmacro{\maximum}{\maximum+\val}
}
\DTLforeach*{dataset}{\nameb=name,\valb=value,\cumval=cumval}{%
\eappto\whattodraw{\noexpand\fill [DSCOLOR\nameb] (axis cs:\cumval,0.5) rectangle %
% node[rotate=90,text width=2cm,align=center] {\nameb} %
++ (axis cs:\valb,1);%
}
}
\begin{document}
\begin{tabular}{cl}
\DTLforeach*{datasetcolor}{\name=namec,\tikzColor=color}{
\tikz\fill[DSCOLOR\name] (0,0) rectangle (2em,1.3ex); & \name \\
}
\end{tabular}
\begin{tikzpicture}
\begin{axis}[
xmin=0,
xmax=\maximum,
ymin=0,
ymax=2,
axis y line=none,
axis x line=bottom,
height=5cm,
legend columns=-1,
width=\textwidth,
xlabel={$t/{\textrm s}\quad (t_{\max} = \maximum)$}
]
\whattodraw
\end{axis}
\end{tikzpicture}
\end{document}
输出
解决方案 2
此解决方案使用 的xbar stacked
样式pgfplots
。无需任何计算,全部由 完成pgfplots
(多亏了stack dir=plus
我们甚至不需要汇总条目)。
遗憾的是,这些scatter
类别和传奇尚未手动构建。
代码
\documentclass{article}
\usepackage[separator={{ }}]{datatool}% loads etoolbox
\usepackage{pgfplots}
\def\whattodraw{}
\begin{filecontents}{dataset.dat}
running 20
stage-out 47
running 34
stage-in 3
running 24
stage-out 39
\end{filecontents}
\begin{filecontents}{datasetcolor.dat}
stage-in red!75
stage-out green
running orange
\end{filecontents}
\DTLloaddb[noheader,keys={name,value},headers={name,value}]{dataset}{dataset.dat}
\DTLloaddb[noheader,keys={name,color},headers={name,color}]{datasetcolor}{datasetcolor.dat}
\DTLforeach{datasetcolor}{\name=name,\tikzColor=color}{
\tikzset{DSCOLOR\name/.estyle={fill=\tikzColor}}
}
\DTLforeach*{dataset}{\namea=name,\vala=value}{%
\eappto\whattodraw{%
\noexpand\addplot[
scatter,
DSCOLOR\namea,
no marks,
draw=none,
scatter src=explicit symbolic
] coordinates {(\vala,0) [\namea]};
}
}
\begin{document}
\ref{legendhere}
\begin{tikzpicture}
\begin{axis}[
xmin=0,
axis y line=none,
axis x line=bottom,
xbar stacked,
stack dir=plus,
height=5cm,
legend columns=-1,
width=\textwidth,
legend to name={legendhere},
scatter/classes={
stage-in={red!75},%
running={orange},%
stage-out={green}}
]
\whattodraw
\legend{stage-in,running,stage-out}
\end{axis}
\end{tikzpicture}
\end{document}
输出
无解决方案pgfplots
代码
\documentclass{article}
\usepackage[separator={{ }}]{datatool}
\usepackage{pgfplots}
\def\maximum{0}
\newlength{\barHeight}\newlength{\barWidth}\newlength{\currentX}\newlength{\nextX}
\setlength{\barHeight}{2cm}
\setlength{\barWidth}{10cm}
\setlength{\currentX}{0cm}
\begin{filecontents}{dataset.dat}
running 20
stage-out 47
running 34
stage-in 3
running 24
stage-out 39
\end{filecontents}
\begin{filecontents}{datasetcolor.dat}
stage-in red!75
stage-out green
running orange
\end{filecontents}
\DTLloaddb[noheader,keys={name,value},headers={name,value}]{dataset}{dataset.dat}
\DTLloaddb[noheader,keys={namec,color},headers={namec,color}]{datasetcolor}{datasetcolor.dat}
\DTLforeach*{datasetcolor}{\name=namec,\tikzColor=color}{
\tikzset{DSCOLOR\name/.estyle={fill=\tikzColor}}
}
\DTLforeach{dataset}{\name=name,\val=value}{
\DTLappendtorow{cumval}{\maximum}
\pgfmathsetmacro{\maximum}{\maximum+\val}
}
\pgfdeclarelayer{background}
\pgfdeclarelayer{main}
\pgfsetlayers{background,main}
\begin{document}
\begin{tikzpicture}
\DTLforeach*{dataset}{\name=name,\val=value}{
\pgfmathsetlength{\nextX}{\val/\maximum*\the\barWidth}
\begin{pgfonlayer}{background}
\fill [DSCOLOR\name] (\the\currentX,0) rectangle ++ (\the\nextX,\the\barHeight);
\end{pgfonlayer}
\draw[|-|,shorten >=-.5\pgflinewidth,shorten <=-.5\pgflinewidth] (\the\currentX,.5*\the\barHeight) -- node [below] {\val} ++ (\the\nextX,0) ;
\pgfmathsetlength{\currentX}{\currentX+\nextX}
}
\end{tikzpicture}
\end{document}