我想创建 x 轴和 y 轴上的刻度列表。我从这篇文章中注意到了一种生成新列表的方法[如何在 pgfplots 中的 tick 定义中使用宏]。
我将该代码修改为以下 MWE。在我的代码中,我想基于列表创建两个刻度列表{0.75,3.5,1.0,1.5,1.0,3.5,1.0,1.5}
。第一个列表只是按顺序将这些值相加。第二个列表是将第一个列表的值加倍。然后,将新生成的列表用作轴的刻度。
\documentclass{article}
\usepackage{tikz}
%% Example code copied from another post.
\newcommand{\deflisttickold}[1]{
\gdef\listticksold{}% global list
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}% count the max number of items
\show \maxitems
\foreach \x[count=\xi] in {#1}{
\ifnum\xi=\maxitems
\xdef\listticksold{\listticks \x}
\else
\xdef\listticksold{\listticks \x,}
\fi
}
}
%% New code modified from \deflisttickold
\newcommand{\deflistticknewone}[1]{
\gdef\listticksnewone{}% global list
\pgfmathsetmacro{\currval}{0.0}
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}% count the max number of items
\foreach \x[count=\xi] in {#1}{
\pgfmathparse{\currval+\x}
\global\edef\currval{\pgfmathresult}
\ifnum\xi=\maxitems
\xdef\listticksnewone{\listticksnewone \currval}
\else
\xdef\listticksnewone{\listticksnewone \currval,}
\fi
}
}
\newcommand{\deflistticknewtwo}[1]{
\gdef\listticksnewtwo{}% global list
\pgfmathsetmacro{\lastval}{0.0}
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}% count the max number of items
\foreach \x[count=\xi] in {#1}{
\pgfmathparse{2.0*(\x-\lastval)}
\global\edef\lastval{\x}
\ifnum\xi=\maxitems
\xdef\listticksnewtwo{\listticksnewtwo \pgfmathresult}
\else
\xdef\listticksnewtwo{\listticksnewtwo \pgfmathresult,}
\fi
}
}
\edef\mylist{0.75,3.5,1.0,1.5,1.0,3.5,1.0,1.5}
\deflisttickold{\mylist}
\deflistticknewone{\mylist}
\deflistticknewtwo{\listticksnewone}
\begin{tikzpicture}
\begin{axis}[
xmode=linear,
ymode=linear,
axis x line*=bottom,
axis y line*=left,
tick label style={font=\small},
grid=both,
tick align=outside,
tickpos=left,
width=0.65\textwidth,
height=0.4\textwidth,
xmin=0,
xtick = \listticksnewone,
xticklabels = \listticksnewone,
ytick = \listticksnewtwo,
yticklabels = \listticksnewtwo,
]
\addplot coordinates {
(0.25, 2.5)
(1.5, 3)
(3.5, 3.5)
(5, 4.5)
(7, 5)
};
\end{axis}
\end{tikzpicture}
\end{document}
但是,我的代码运行得不太好。如果我使用给定的代码复制列表,则新生成的列表\deflisttickold{\mylist}
确实是列表。\deflistticknewone{\mylist}
和生成的列表\deflistticknewtwo{\listticksnewone}
是不正确的。
有人能帮我找出问题吗?提前谢谢了。
答案1
一种方法是采用在 TikZ/PGFplots 中使用宏定义列表并定义一种x tick labels list
风格:
\edef\temp{\noexpand\pgfplotsset{x tick labels list/.style={xticklabels={\MyDoubleList}}}}
\temp
新的列表在哪里\MyDoubleList
,然后将其作为选项应用于环境axis
。
要根据旧列表创建新列表,请执行以下操作:
定义一个宏,返回根据给定值计算出的新值。例如:
\newcommand*{\MultiplyByTwo}[1]{2*#1}%
将使提供的价值加倍。
调用
\DefineNewList
宏并传入% #1 = macro to contain new list % #2 = function which evaluates new list member based on old list member % #3 = old list
因此,如果
\mylist
包含您的原始列表,则调用\DefineNewList{\MyDoubleList}{\MultiplyByTwo}{\mylist}
创建一个列表
\MyDoubleList
,其中每个元素都是 中的值的两倍\mylist
。
将它们放在一起会在 x 轴上产生标签,0.5, 2.0, 4.0
其值为实际值的两倍:
代码:
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\makeatletter
\newcommand*{\@tempDefineNewList}{}% Ensure it is not already defined
\newcommand*{\DefineNewList}[3]{%
% #1 = macro to contain new list
% #2 = function which evaluates new list member based on old list member
% #3 = old list
\gdef#1{}% Initialize
\edef\expandedOldList{#3}%
\foreach [count=\xi] \x in \expandedOldList {%
\pgfmathsetmacro{\@tempDefineNewList}{#2{\x}}%
\ifnum\xi=1\relax
\xdef#1{\@tempDefineNewList}%
\else
\xdef#1{#1, \@tempDefineNewList}%
\fi
}%
}%
\makeatother
\newcommand*{\MultiplyByTwo}[1]{2*#1}%
\newcommand*{\MultiplyByThree}[1]{2*#1}%
\newcommand\mylist{0.5, 2.0, 4.0}
\DefineNewList{\MyDoubleList}{\MultiplyByTwo}{\mylist}
\DefineNewList{\MyTripleList}{\MultiplyByThree}{\mylist}
%% https://tex.stackexchange.com/questions/17833/using-macro-defined-lists-in-tikz-pgfplots
\edef\temp{\noexpand\pgfplotsset{x tick labels list/.style={xticklabels={\MyDoubleList}}}}%
\temp
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmode=linear,
ymode=linear,
axis x line*=bottom,
axis y line*=left,
tick label style={font=\small},
grid=both,
tick align=outside,
tickpos=left,
width=0.65\textwidth,
height=0.4\textwidth,
xmin=0,
xtick=\mylist,
x tick labels list,% <-- see effect of commenting this out.
]
\addplot coordinates {
(0.25, 2.5)
(1.5, 3)
(3.5, 3.5)
(5, 4.5)
(7, 5)
};
\end{axis}
\end{tikzpicture}
答案2
我找到了我的问题的答案。
代码段如下。
\newcommand{\deflisttick}[1]{
\gdef\listticks{}% global list
\pgfmathsetmacro{\currval}{0.0}
\foreach \x [count=\xi] in #1 {\global\edef\maxitems{\xi}}% count the max number of items
\foreach \x [count=\xi] in #1 {
\pgfmathparse{\currval+\x}
\global\edef\currval{\pgfmathresult}
\ifnum\xi=\maxitems
\global\edef\listticks{\listticks \currval}
\else
\global\edef\listticks{\listticks \currval,}
\fi
}
}
\edef\mylist{0.75,3.5,1.0,1.5,1.0,3.5,1.0,1.5}
\deflisttick{\mylist}
\begin{tikzpicture}
\begin{axis}[
xmode=linear,
ymode=linear,
axis x line*=bottom,
axis y line*=left,
tick label style={font=\small},
grid=both,
tick align=outside,
tickpos=left,
width=0.65\textwidth,
height=0.4\textwidth,
xmin=0, xmax=15,
xtick = \listticks,
]
\addplot coordinates {
(0.25, 2.5)
(1.5, 3)
(3.5, 3.5)
(5, 4.5)
(7, 5)
};
\end{axis}
\end{tikzpicture}