![使用两个独立但同步的纵坐标轴创建 pgfplots 图形](https://linux22.com/image/467140/%E4%BD%BF%E7%94%A8%E4%B8%A4%E4%B8%AA%E7%8B%AC%E7%AB%8B%E4%BD%86%E5%90%8C%E6%AD%A5%E7%9A%84%E7%BA%B5%E5%9D%90%E6%A0%87%E8%BD%B4%E5%88%9B%E5%BB%BA%20pgfplots%20%E5%9B%BE%E5%BD%A2.png)
在下面的 MWE 和图表中,
目前,下图由对数缩放的 X 轴和 Y 轴组成,单位为:
- 横坐标 (X) 为 log(years),以及
- 分别在(传统)纵坐标(Y)轴上记录($)。
然而,虽然:
左 (Y)(传统)纵坐标轴以 10 为基数对数的, 这
右(X)(新的,唯一的)纵坐标轴是意味着成为线性例如非-对数的。
左纵轴和右纵轴均为意味着要同步,例如,左纵轴上显示的对数值需要在非对数形式上等同于右纵轴上显示的值。
在下面的当前图表中,左纵坐标轴是确切地正如我希望的那样,但右纵坐标轴是不是.横坐标为确切地正如它需要的那样。
挑战在于左纵轴是对数,但右纵坐标轴是不是。
因此,我希望右纵坐标轴能够适当地显示 1,050($)、1,100($) 和 1,150($) 处的“刻度”标记,大致对应于左纵坐标轴上的值 10^3.02、10^3.04和 10^3.06。
在下图中,左侧纵坐标轴上标签为 10^3.0 的水平2log($),在右纵坐标轴上我希望看到(大约,不完全是)非-对数‘刻度’标记和标签 1,050(美元)。
类似地,在左纵坐标轴上标签 10^3.0 指示的级别6log($),在右纵坐标轴上我希望看到(大约,不完全是)非-对数‘刻度’标记和标签 1,150(美元)。
以下是当前的 MWE:
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
name=left axis,
xmode=log,
xlabel={Year (log scale)},
ylabel={Cumulative Future Asset Value (log \$ scale)},
ylabel near ticks,
ylabel shift = -0.35em,
legend pos=north west,
ymajorgrids=true,
grid style=dashed,
xtick={1,10,100},
xticklabels={1,10,100},
ytick={3.00, 3.02, 3.04, 3.06},
yticklabels={$10^{3.00}$, $10^{3.02}$, $10^{3.04}$, $10^{3.06}$},
y tick label style={font=\large},
]
% For r=5%
\addplot[color=blue,domain=1:100,samples=100]
{log10(1000 * (1 + 0.05)^(log10(\x+1)))};
\addlegendentry{$r=5\%$}
% For r=7%
\addplot[color=red,domain=1:100,samples=100]
{log10(1000 * (1 + 0.07)^(log10(\x+1)))};
\addlegendentry{$r=7\%$}
\end{axis}
\begin{axis}[
at={(left axis.outer north east)},anchor=outer north west,
yshift=-0.2cm,
xshift=-0.161cm,
yticklabel style={font=\large},
ytick={2000, 3000, 4000, 5000, 6000, 7000, 8000},
yticklabels={2000, 3000, 4000, 5000, 6000, 7000, 8000},
ylabel near ticks,
ylabel={Absolute Future Asset Value (\$)},
xtick=\empty,
axis y line*=right,
axis x line=none,
scale only axis,
ymode=log,
yticklabel={\pgfmathprintnumber[fixed, precision=0, use comma]{\tick}},
]
\end{axis}
\end{tikzpicture}
\end{document}
目前的图表如下:
目前,该图由对数缩放的 X 轴和 Y 轴组成,横坐标(X)轴上的单位为 log(年),(传统)左纵坐标(Y)轴上的单位为 log($)。
独特、非传统的,非- 对数右线性 $ 纵坐标轴旨在帮助那些可能不理解如何解释左对数($) 纵坐标轴上的对数值的读者。
我浏览了 Christian Feuersänger 博士的大量pgf图包文档,但没有看到任何此类双坐标图形的具体示例。
顺便说一句,我花了大约 15 个小时在线与 AI 合作,试图得到我想要的东西。我(和 AI)遇到的最大障碍是这个特定的 AI 无法从 LaTeX 代码中绘制图形,因此无法想象或“看到”它建议的代码的输出。这是一个重大缺点。
到目前为止,这也是使用人工智能的棘手之处,我(或者我应该说我们?)能够构建现在的图表。不幸的是,调整右纵坐标轴上的标签和“刻度”标记却很难。
这可能只是一场空洞的演习,pgf图包无法处理,证实了人工智能所面临的困难。
如果您有任何问题,请随时向我提问。我试图呈现的并不是传统概念,尤其是对于那些可能从未见过这种图表的(经济学家类型的)读者来说。
非常感谢。
更新:使用 Rmano 的代码(见下文)和一些调整,双轴图形绘图的最终代码是:
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}
\pgfplotsset{range/.style={%
xmin = 0.9,
xmax = 200,
ymin = 3.0,
ymax= 3.07,
}}
\begin{axis}[
range,
name=left axis,
xmode=log,
xlabel={Year (log scale)},
ylabel={Cumulative Future Asset Value (log \textdollar{} scale)},
legend pos=north west,
ymajorgrids=true,
grid style=dashed,
xtick={1,10,100},
xticklabels={1,10,100},
ytick={3.00, 3.02, 3.04, 3.06},
yticklabels={$10^{3.00}$, $10^{3.02}$, $10^{3.04}$, $10^{3.06}$},
ylabel near ticks,
y tick label style={font=\large},
axis y line* = left,
]
% For r=5%
\addplot[color=blue,domain=1:100,samples=100]
{log10(1000 * (1 + 0.05)^(log10(\x+1)))};
\addlegendentry{$r=5\%$}
% For r=7%
\addplot[color=red,domain=1:100,samples=100]
{log10(1000 * (1 + 0.07)^(log10(\x+1)))};
\addlegendentry{$r=7\%$}
\end{axis}
\begin{axis}[
range,
xmode=log,
yticklabel style={font=\large},
ylabel near ticks,
% this is the same value as the other vertical axis, no sense
% to have a different label...
ylabel={Absolute Future Asset Value (\textdollar)},
% we need ticks at the correct position. fpeval have no log10
% surely can be automated
ytick={\fpeval{ln(1000)/ln(10)},
\fpeval{ln(1050)/ln(10)},
\fpeval{ln(1100)/ln(10)},
\fpeval{ln(1150)/ln(10)}},
yticklabels={{1,000},{1,050},{1,100},{1,150}},
axis y line*=right,
axis x line=none,
]
\end{axis}
\end{tikzpicture}
\end{document}
最终的图表为:
答案1
这是我对这个问题的另一种解释。请注意,对于pgfplots
,左侧的垂直轴是线性的,不是对数的。“对数”是使用log10
绘图函数中的 手动创建的。该函数绘制在线性轴上,范围从 3.0 到 3.065。
一旦绘制了函数,就不能让线性轴与对数轴匹配(反之亦然)。我想你想要一个具有明确值的辅助轴$10^{3.02}$
……
在这种情况下,当使用多个轴时,我认为最好的办法是固定 x 和 y 范围(你可以为此使用通用样式)。然后我手动计算了ytick
右侧垂直轴上的位置,即相同和左边的一样。
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}
\pgfplotsset{range/.style={%
xmin = 0.9,
xmax = 200,
ymin = 3.0,
ymax= 3.07,
}}
\begin{axis}[
range,
name=left axis,
xmode=log,
xlabel={Year (log scale)},
ylabel={Cumulative Future Asset Value (log \textdollar{} scale)},
legend pos=north west,
ymajorgrids=true,
grid style=dashed,
xtick={1,10,100},
xticklabels={1,10,100},
ytick={3.00, 3.02, 3.04, 3.06},
yticklabels={$10^{3.00}$, $10^{3.02}$, $10^{3.04}$, $10^{3.06}$},
ylabel near ticks,
y tick label style={font=\large},
axis y line* = left,
]
% For r=5%
\addplot[color=blue,domain=1:100,samples=100]
{log10(1000 * (1 + 0.05)^(log10(\x+1)))};
\addlegendentry{$r=5\%$}
% For r=7%
\addplot[color=red,domain=1:100,samples=100]
{log10(1000 * (1 + 0.07)^(log10(\x+1)))};
\addlegendentry{$r=7\%$}
\end{axis}
\begin{axis}[
range,
xmode=log,
yticklabel style={font=\large},
ylabel near ticks,
% this is the same value as the other vertical axis, no sense
% to have a different label...
%%% ylabel={Absolute Future Asset Value (\textdollar)},
% we need ticks at the correct position. fpeval have no log10
% surely can be automated
ytick={\fpeval{ln(1000)/ln(10)},
\fpeval{ln(1050)/ln(10)},
\fpeval{ln(1100)/ln(10)},
\fpeval{ln(1150)/ln(10)}},
yticklabels={1000,1050,1100,1150},
axis y line*=right,
axis x line=none,
]
\end{axis}
\end{tikzpicture}
\end{document}
答案2
不完全确定这是否是你想要的,但如果你想绘制两个坐标,你需要将选项设置scale only axis
为两个都轴,以便匹配两个轴的缩放比例(如何使用两个坐标系实际上在当前PGFlots 手册,但也许你使用的AI还没有详细阅读这一部分......