我使用以下数据绘制了一条三维线:
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
我想绘制此 3D 图的横截面(即 2D 图 - 例如通过 p 1 =0 的平面)
我想要 3D 图中的一个虚线矩形来表示我正在绘制的横截面。
如何使 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
库来实现这一点。