我有\points
一个数组,我想自动将xtick
和添加ytick
到我的轴上。我该怎么做?
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\def\points{{{-9,0.30},{-6,0.44},{-2,0.59},{3,1}}}
\pgfmathsetmacro{\len}{dim(\points)-1}
\begin{axis}
[
axis lines = center,
axis line style = thick,
% xtick= loop here for \points[\i][0]
% ytick= loop here for \points[\i][1] where \i=0,...,\len
clip=false
]
\addplot ({x},{x^2});
\end{axis}
\end{tikzpicture}
\end{document}
答案1
不需要循环。
问题是,你的 MWE 的点与你的曲线无关(忽略opacity=0
它们),它们既不在曲线上也不在曲线附近,因此图形表示效果不好。
我认为使用你的实际点和曲线会更好。
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}
\def\points{(-9,0.30) (-6,0.44) (-2,0.59) (3,1)}
\begin{axis}[scale=1.5,
xtick=data,
ytick=data,
axis lines = center,
axis line style = thick,
clip=false
]
\addplot[only marks,
opacity=0]
coordinates {\points};
\addplot ({x},{x^2});
\end{axis}
\end{tikzpicture}
\end{document}
答案2
这里我使用 来\foreach
循环并构建分别存储在和\points
中的 x 和 y 坐标列表。然后只需在环境中进行设置即可。\pointsX
\pointsY
xtick=\pointsX
axis
将所有这些包装到一个新的处理程序中会很简洁,但是-list 和-arraypgfkeys
之间的差异使泛化变得非常困难。\foreach
pgfmath
\documentclass{article}
\usepackage{etoolbox}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\def\points{{{-9,0.30},{-6,0.44},{-2,0.59},{3,1}}}
\pgfmathsetmacro{\len}{dim(\points)-1}
\def\pointsX{}
\def\pointsY{}
\foreach \i in {0,...,\len} {
\pgfmathsetmacro{\x}{\points[\i][0]}
\pgfmathsetmacro{\y}{\points[\i][1]}
\ifnum\i=0
\xappto\pointsX{\x}
\xappto\pointsY{\y}
\else
\xappto\pointsX{,\x}
\xappto\pointsY{,\y}
\fi
}
\begin{axis}
[
axis lines = center,
axis line style = thick,
xtick=\pointsX,
ytick=\pointsY,
clip=false
]
\addplot ({x},{x^2});
\end{axis}
\end{tikzpicture}
\end{document}
答案3
基本上,问题在于生成这种数组{<num1>, <num2>, <num3>, ...}
。这似乎相当棘手,但我设法找到了解决方案。
解决问题的关键是扩张. \xdef
(相当于\global\edef
)允许定义扩展宏,以便它可以在其定义中访问自身。例如
\edef\foo{-3} % -> -3
\edef\foo{\foo,6} % -> -3,6
第一个基于\push
宏的解决方案是我在这个帖子. 下面的代码构成了所需的数组
\def\push#1#2{\expandafter\xdef\csname #1\endcsname{\expandafter\ifx\csname #1\endcsname\empty\else\csname #1\endcsname,\fi#2}}
\def\xarr{}
\def\yarr{}
\foreach \i [evaluate={\x=\points[\i][0]; \y=\points[\i][1]}] in {0,...,\len}{
\push{xarr}{\x}
\push{yarr}{\y}
}
第二种解决方案不需要宏,但仍然基于扩展定义
\def\xarr{}
\def\yarr{}
\foreach \i [evaluate={\x=\points[\i][0]; \y=\points[\i][1]; \c=ifthenelse(\i<\len,",",)}] in {0,...,\len}{
\xdef\xarr{\xarr\x\c}
\xdef\yarr{\yarr\y\c}
}
平均能量损失
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\def\points{{{-9,0.30},{-6,0.44},{-2,0.59},{3,1}}}
\pgfmathsetmacro{\len}{dim(\points)-1}
\def\push#1#2{\expandafter\xdef\csname #1\endcsname{\expandafter\ifx\csname #1\endcsname\empty\else\csname #1\endcsname,\fi#2}}
\def\xarr{}
\def\yarr{}
% First method
%\foreach \i [evaluate={\x=\points[\i][0]; \y=\points[\i][1]}] in {0,...,\len}{
% \push{xarr}{\x}
% \push{yarr}{\y}
%}
% Second method
\foreach \i [evaluate={\x=\points[\i][0]; \y=\points[\i][1]; \c=ifthenelse(\i<\len,",",)}] in {0,...,\len}{
\xdef\xarr{\xarr\x\c}
\xdef\yarr{\yarr\y\c}
}
\begin{axis}
[
axis lines = center,
axis line style = thick,
% xtick= loop here for \points[\i][0]
% ytick= loop here for \points[\i][1] where \i=0,...,\len
clip=false
]
\addplot ({x},{x^2});
\end{axis}
\end{tikzpicture}
\end{document}
请注意,如果您添加了babel
包,第二种方法可能会抛出错误。这都是因为"
inside ifthenelse
。为了解决这个问题,请使用ifthenelse(\i<\len,\string",\string",)
,或者使用\shorthandoff{"}
。