pgfplots:在文件中两个坐标之间绘制线

pgfplots:在文件中两个坐标之间绘制线

我基本上有一个包含大约 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}

相关内容