pgfplots 从数组中添加 xtick

pgfplots 从数组中添加 xtick

我有\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\pointsYxtick=\pointsXaxis

将所有这些包装到一个新的处理程序中会很简洁,但是-list 和-arraypgfkeys之间的差异使泛化变得非常困难。\foreachpgfmath

\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{"}

相关内容