Pgfplot-3D 线图的横截面(庞加莱截面)

Pgfplot-3D 线图的横截面(庞加莱截面)

我使用以下数据绘制了一条三维线:

p p1t p2t
-65.79  -210.81 137.73
-124.76 -182.7  189.67
-170.78 -141.97 233.17
-206.39 -96.42  257.48
-226.99 -40.212 268.45
-231.57 20.337  255.59
-226.75 78.518  223.62
-210.81 137.73  175.85
-182.7  189.67  113.02
-141.97 233.17  46.467
-96.42  257.48  -21.029
-40.212 268.45  -88.289
20.337  255.59  -145.29
78.518  223.62  -187.76
137.73  175.85  -219.49
189.67  113.02  -236.46
233.17  46.467  -239.94
257.48  -21.029 -232.83
268.45  -88.289 -215.23
255.59  -145.29 -188.55
223.62  -187.76 -150.57
175.85  -219.49 -105.58
113.02  -236.46 -53.317
46.467  -239.94 8.5742
-21.029 -232.83 69.439
-88.289 -215.23 133.3
-145.29 -188.55 189.99
-187.76 -150.57 237.67
-219.49 -105.58 270.35
-236.46 -53.317 280.53
-239.94 8.5742  273.67
-232.83 69.439  242.25
-215.23 133.3   192.67
-188.55 189.99  124.54
-150.57 237.67  54.914
-105.58 270.35  -17.003
-53.317 280.53  -84.499
8.5742  273.67  -144.65
69.439  242.25  -186.34
133.3   192.67  -215.7
189.99  124.54  -232.52
237.67  54.914  -232.44
270.35  -17.003 -224.46
280.53  -84.499 -207.1
273.67  -144.65 -179.78
242.25  -186.34 -143
192.67  -215.7  -100.92
124.54  -232.52 -51.028
54.914  -232.44 5.9691
-17.003 -224.46 64.545
-84.499 -207.1  124.38
-144.65 -179.78 178.78
-186.34 -143    225.43
-215.7  -100.92 259.53
-232.52 -51.028 273.98
-232.44 5.9691  271.22
-224.46 64.545  241.22
-207.1  124.38  191.33
-179.78 178.78  128.33
-143    225.43  57.519
-100.92 259.53  -12.74
-51.028 273.98  -82.841
5.9691  271.22  -138.81
64.545  241.22  -184.6
124.38  191.33  -216.97
178.78  128.33  -231.49
225.43  57.519  -232.67

情节将会是这样的。 在此处输入图片描述 现在,

  1. 我想绘制此 3D 图的横截面(即 2D 图 - 例如通过 p 1 =0 的平面)

  2. 我想要 3D 图中的一个虚线矩形来表示我正在绘制的横截面。

  3. 如何使 x、y 和 z 标签与它们各自的轴平行?

以下是 MWE:

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{graphicx}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{mathtools}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis}[xlabel=p1, ylabel=p1t, zlabel=p2t, tick style={draw=none}]

\addplot3[smooth, mark=none, color=black] table [x=p, y=p1t, z=p2t]{dummy.txt};

\end{axis}
\end{tikzpicture}
\end{document}

进度更新:尽管方法对于曲面图执行此操作,对于线图则不行。

答案1

我会使用拆分方法,真的——我在这里发布这篇文章是因为我确信具有 Lua 技能的人会将其集成到独立的 LaTeX 源中。碰巧我懂 Python……我会从另一个答案中学习 :-)

因此我创建了这个快速而粗糙的python脚本来通过线性插值来查找截距:

#! /usr/bin/env python3
#
# use as ./process.py filename x-coordinate-to-cut
# 
import sys
xcut = float(sys.argv[2])
with open(sys.argv[1]) as f:
    i=-1
    for line in f:
        i += 1
        if i==0:
            print ("p1t p2t")
            continue # skip first line
        data = [float(f) for f in line.split()]
        if i==1:
            old_data = data 
            continue
        if (old_data[0] <= xcut and data[0] > xcut) or (old_data[0] >= xcut and data[0] < xcut):
            # crossing the plane
            y = old_data[1] + (data[1]-old_data[1])/(data[0]-old_data[0])*(xcut - old_data[0])
            z = old_data[2] + (data[2]-old_data[2])/(data[0]-old_data[0])*(xcut - old_data[0])
            print("%g %g" % (y,z))
        old_data = data

并使用它为切割创建数据点p=0

./process.py dummy.txt 0.0 > cross0.txt
./process.py dummy.txt 100.0 > cross100.txt
./process.py dummy.txt 200.0 > cross200.txt

现在来看看来源:

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}
\usepackage{graphicx}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{mathtools}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis}[xlabel=p1, ylabel=p1t, zlabel=p2t, tick style={draw=none},
    xmin=-300, xmax=300, ymin=-300, ymax=300, zmin=-300, zmax=300]
    \addplot3[smooth, mark=none, color=black] table [x=p, y=p1t, z=p2t]{dummy.txt};
    \draw [dashed, red] (0,-300,-300) -- (0,300,-300) -- (0,300,300) -- (0,-300,300) -- cycle; 
    \draw [dashed, blue] (100,-300,-300) -- (100,300,-300) -- (100,300,300) -- (100,-300,300) -- cycle; 
    \draw [dashed, green] (200,-300,-300) -- (200,300,-300) -- (200,300,300) -- (200,-300,300) -- cycle; 
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
    \begin{axis}[xlabel=p1t, ylabel=p2t, tick style={draw=none},
        xmin=-300, xmax=300, ymin=-300, ymax=300]
        \addplot [red, only marks] table [x=p1t, y=p2t]{cross0.txt};
        \addplot [blue, only marks] table [x=p1t, y=p2t]{cross100.txt};
        \addplot [green, only marks] table [x=p1t, y=p2t]{cross200.txt};
        \legend{$p=0$, $p=100$, $p=200$}
    \end{axis}
\end{tikzpicture}

\end{document}

我得到的结果是:

好的,现在是正确的

这显然需要一点爱来按摩,但我认为这或多或少是 OP 想要的。

答案2

以下是相同的答案Rmano 的一个但在 Lualatex 中,所有内容都在同一个文件中:

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{luacode}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis}[xlabel=p1, ylabel=p1t, zlabel=p2t, tick style={draw=none},
    xmin=-300, xmax=300, ymin=-300, ymax=300, zmin=-300, zmax=300]
    \addplot3[smooth, mark=none, color=black] table [x=p, y=p1t, z=p2t]{dummy.txt};
    \draw [dashed, red] (0,-300,-300) -- (0,300,-300) -- (0,300,300) -- (0,-300,300) -- cycle; 
    \draw [dashed, blue] (100,-300,-300) -- (100,300,-300) -- (100,300,300) -- (100,-300,300) -- cycle; 
    \draw [dashed, green] (200,-300,-300) -- (200,300,-300) -- (200,300,300) -- (200,-300,300) -- cycle; 
\end{axis}
\end{tikzpicture}

\begin{luacode*}
function split(str)
    return {str:match("([^ ]*) +([^ ]*) +([^ ]*)")}
end
function plot_crosssection(filename,p1val)
    local i=0
    local data,olddata
    for line in io.lines(filename) do
        print (i,data)
        i=i+1
        if i==2 then data=split(line)
        elseif i>2 then
            olddata={data[1],data[2],data[3]}
            data=split(line)
            if (olddata[1]-p1val)*(data[1]-p1val)<=0 then
                local y = olddata[2] + (data[2]-olddata[2])/(data[1]-olddata[1])*(p1val - olddata[1])
                local z = olddata[3] + (data[3]-olddata[3])/(data[1]-olddata[1])*(p1val - olddata[1])
                tex.sprint("("..y..","..z..")")
            end
        end
    end
end
\end{luacode*}
\begin{tikzpicture}
    \begin{axis}[xlabel=p1t, ylabel=p2t, tick style={draw=none},
        xmin=-300, xmax=300, ymin=-300, ymax=300]
        \addplot [red, only marks] coordinates {\directlua{plot_crosssection("dummy.txt",0);}};
        \addplot [blue, only marks] coordinates {\directlua{plot_crosssection("dummy.txt",100);}};
        \addplot [green, only marks] coordinates {\directlua{plot_crosssection("dummy.txt",200);}};
        \legend{$p=0$, $p=100$, $p=200$}
    \end{axis}
\end{tikzpicture}

\end{document}

用 编译它lualatex。我使用了一种非常简单的方法来读取此.txt文件,但您也可以使用该csv.lua库来实现这一点。

相关内容