我基本上有一个包含大约 100 行的选项卡单独文件。每行有三个值:A、B 和 C。
我想循环遍历数据文件中的每一行,并在坐标 (A,B) 和 (A,C) 之间绘制一条线。pgfplots 文档中的示例没有明确说明如何执行此操作。
例如,假设我在单独的文件中有以下数据:
A、B、C
1、2、3
2、2.5、4
我想获取该文件并循环遍历其行,在此过程中绘制单独的线条。在第一行中,我想绘制一条从 (1,2) 到 (1,3) 的线。在第二行中,绘制一条从 (2, 2.5) 到 (2, 4) 的线,依此类推。
答案1
我可能会因此被否决,但我会用你最喜欢的脚本语言编写一个程序来生成你想要的 TikZ 代码。下面是 Python 中的一个代码:
from contextlib import contextmanager
from textwrap import dedent
import re
import sys
def formatter(string_to_be_printed, **kwargs):
"""
Perform recursive string formatting on a string.
Any keywords enclosed in curly quotation marks are expanded using the
keyword arguments passed into the function with a few details:
The formatter is applied recursively to the expanded string.
If a keyword is a comma-separated list like so “a, b, c”, then each of
the keywords "a", "b", and "c" are expanded and the results of joined with
intervening commas. If any expansion results in the None object, the
formatter acts as if that term were not there.
Any keyword can contain a ':' in which case the Python string formatting
applies, e.g., “a:.6f” would look for 'a' in the keyword arguments and
expanded the floating point number to six decimal places.
Finally, the returned string is unindented and stripped of whitespace
at either end.
"""
def repl(m):
keyword = m.group(1)
retval = []
for x in keyword.split(','):
x = x.strip()
if x == '':
assert not retval
retval.append('')
continue
if kwargs[x.split(':')[0]] is not None:
y = ('{' + x + '}').format(**kwargs)
retval.append(str(y))
retval = ", ".join(retval)
return retval
retval = re.sub(r"“(.+?)”", repl, dedent(string_to_be_printed)).strip()
if '“' in retval:
return formatter(retval, **kwargs)
return retval
def pf(string_to_be_printed, file=sys.stdout, end='\n', **kwargs):
"""
Format the string using formatter and print it to file with the given
ending character. File defaults to stdout and end to '\n'.
"""
print(formatter(string_to_be_printed, **kwargs), end=end, file=file)
@contextmanager
def tex_pic(f, filename, pic_type, options={}):
"""
A context manager that creates a tikzpicture environment in the given
file. filename is the name of the generated pdf for the tikz code.
"""
pf(r"""
\tikzsetnextfilename{“filename”}
\begin{tikzpicture}[“pic_type”]
""",
pic_type=pic_type,
filename=filename,
file=f,
**options)
yield
pf(r"""
\end{tikzpicture}
""",
end='\n\n',
file=f)
with open('a.tex', 'wt') as f:
pf(r"""
\documentclass{minimal}
\usepackage{pgfcore}
\usepackage{pgfkeys}
\usepackage{pgfplots}
\usetikzlibrary{
external,
}
\tikzexternalize[prefix=figures/]
\begin{document}
""",
file=f)
with tex_pic(f, 'diagram', ''):
with open('coords.txt') as g:
for line in g:
x, y, z = [float(x) for x in line.split()]
pf(r"\draw (“x”, “y”) -- (“x”, “z”);", x=x, y=y, z=z,
file=f)
pf(r"""
\end{document}
""",
file=f)
它生成的.tex 文件如下所示:
\documentclass{minimal}
\usepackage{pgfcore}
\usepackage{pgfkeys}
\usepackage{pgfplots}
\usetikzlibrary{
external,
}
\tikzexternalize[prefix=figures/]
\begin{document}
\tikzsetnextfilename{diagram}
\begin{tikzpicture}[]
\draw (1.0, 2.0) -- (1.0, 3.0);
\draw (2.0, 2.5) -- (2.0, 4.0);
\end{tikzpicture}
\end{document}
真正神奇的是pf
进行字符串格式化的函数。由于 tex 使用{}()[]
广泛,我最终使用了花括号“”,在 Mac 键盘上是 option-[ 和 option-shift-[。格式化是递归完成的(与常规 Python 格式化不同),有时很有用。
请注意,实际读取文件并生成图像的代码仅为块with tex_pic
(6 行)。通常可以轻松添加其他图像。
答案2
您可以使用此error bars
功能实现此目的:
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}
\begin{filecontents}{data.csv}
A,B,C
1,2,3
2,2.5,4
\end{filecontents}
\begin{document}
\begin{tikzpicture}
\begin{axis}[axis equal image, enlargelimits=0.5]
\addplot [
no markers, draw=none,
error bars/y dir=plus,
error bars/y explicit,
error bars/error mark=none,
error bars/error bar style=very thick
] table [
col sep=comma,
y error expr=\thisrow{C}-\thisrow{B}] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}