我有一个很大的数据集,其中有一列是:
1
1+n
...
n
我需要用 坐标绘制图0 ... 1
。
如何使用 pgfplots 来做这件事?
需要根据 y (第二列)绘制图表0 to 1
。
我的数据文件: 文件
最小代码:
\documentclass[final]{scrreprt}
\usepackage{filecontents}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot table [mark=none, skip first n=1, x index=0, y index=1, col sep=space] {I100-3.csv};
\end{axis}
\end{tikzpicture}
\end{document}
执行命令:
pdflatex -shell-escape -output-directory="$dir" "$base" "$file"
答案1
a
需要四个值来规范化表格的两个轴:列和的最大值和最小值b
。
由于列a
是按顺序排列的,因此很容易通过各种方法获取其第一个值和最后一个值,从而获取最小值和最大值。例如,参见按序列的第 i 个值进行归一化通过扫描数据库来完成。
对于列,b
情况就不同了。通常的方法是加载数据库或表,按降序对列进行排序,然后检索第一个和最后一个值。有时,大型表的排序存在内存限制。或者从头到尾扫描表以找到最大值和最小值(速度较慢但不占用太多内存)。
坏消息是这需要时间,特别是对于 10K 行或更多行时,并且每次编译图形或文档时都必须重复此操作。
(当然,您可以执行一次,然后将该图保存为,.pdf
以类似的方式将其合并到文档中externalize
。)
该表由 LaTeX 之外的系统生成,可能是数据采集系统的输出、对统计数据库的查询或模拟结果等,并导出到 Tikz。我知道,在一些系统中,这些外部系统可以被指示提供最大值、最小值、日期、总运行时间、ID 和其他相关数据,元数据伴随原始数据。
如果这不可能,您可以按照我在本例中所做的操作:将数据加载到 excel 中(重命名为I100-3.txt
,因为导入 excel 更容易)并一次对列进行排序,检索它们的最大值和最小值。总时间:30 秒,仅执行一次。
有关更自动化的方法,请参阅最后的代码。
注意:要使用另一个目录作为输出,例如OutputDir
工作目录的子目录,语法为
pdflatex.exe -synctex=1 -interaction=nonstopmode -shell-escape -output-directory=./OutputDir/ <filename>.tex
(输出前只有一个破折号)
\documentclass[final]{scrreprt}
%%\usepackage{filecontents} % not needed
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
% ********** Had them before, outside of LaTex
\newcommand{\Minia}{20}
\newcommand{\Maxa}{139.99}
\newcommand{\Minib}{346} % a = 56.51
\newcommand{\Maxb}{1416} % a = 39.09
%%************************
\begin{document}
\tikzset{mark options={mark size=0.1}}
\begin{figure}
\centering
\begin{tikzpicture}
\begin{axis}
\addplot table [only marks,
x index = {0}, y index = {1},
y expr = (\thisrowno{1}-\Minib)/(\Maxb-\Minib),
x expr = (\thisrowno{0}-\Minia)/(\Maxa-\Minia),
col sep = space,
skip first n=1,
] {I100-4.csv};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document
作为参考,显示标准化之前的原始数据。
无需使用 Excel,该软件包pgfplotstable
就能够完成这项工作。
这是摘自 对加载数据进行数学运算
它在中型 PC 上大约需要 250 秒(12K 行表)才能完成工作。扫描表格两次并输出每列的最大值和最小值。
可以将该图添加到页面中作为参考。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\newcommand{\Minia}{}
\newcommand{\Maxa}{}
\newcommand{\Minib}{}
\newcommand{\Maxb}{}
\newcommand{\findminmax}[1]{% https://tex.stackexchange.com/a/442061/161015
\pgfplotstablegetrowsof{\mytable}
\pgfmathtruncatemacro{\numrows}{\pgfplotsretval-1} % because the tabla has header row
\typeout{\numrows\space data rows; column-> #1}% keep the user informed
\pgfplotstablegetelem{1}{#1}\of{\mytable}
\pgfmathtruncatemacro{\mymax}{\pgfplotsretval} % initial value
\pgfmathtruncatemacro{\mymin}{\pgfplotsretval}
\pgfplotsinvokeforeach {1,...,\numrows}{% scans all rows from column #1
\pgfplotstablegetelem{##1}{#1}\of{\mytable}
\pgfmathsetmacro{\mymax}{max(\pgfplotsretval,\mymax)} % choose the higher value
\pgfmathsetmacro{\mymin}{min(\pgfplotsretval,\mymin)} % choose the lower value
}
\typeout{final mini found:\space\mymin} % keep the user informed
\typeout{final max found:\space\mymax}
\ifnum#1=0 \xdef\Minia{\mymin}\xdef\Maxa{\mymax}\fi % broadcast
\ifnum#1=1 \renewcommand{\Minib}{\mymin}\renewcommand{\Maxb}{\mymax}\fi
}
\begin{document}
\pgfplotstableread[skip first n=1, x index=0, y index=1, col sep=space]{I100-3.csv}\mytable
\findminmax{0}
\section{Ref: run I100-3.csv}
\noindent Rows = \numrows
\noindent Min a = \Minia
\noindent Max a = \Maxa
\findminmax{1}
\noindent Min b = \Minib
\noindent Max b = \Maxb
%%% ************************** uncomment the following lines to add the figure
%%% **************************
%\begin{figure}[ht!]
%\tikzset{mark options={mark size=0.1}}
% \centering
% \begin{tikzpicture}
% \begin{axis}
% \addplot table [only marks,
% x index = {0}, y index = {1},
% y expr = (\thisrowno{1}-\Minib)/(\Maxb-\Minib),
% x expr = (\thisrowno{0}-\Minia)/(\Maxa-\Minia),
% col sep = space,
% skip first n=1,
% ] {I100-3.csv};
% \end{axis}
% \end{tikzpicture}
%\end{figure}
\end{document}