这是一个后续问题未明确设置时轴限制的键名称axis
。那里给出的解决方案对于常规 PGFplots环境非常有效,但对于loglog
轴环境则不然。\pgfkeysgetvalue{/pgfplots/...}{...}
轴中的命令\pgfplotsextra
似乎无法正常工作loglog
。我该如何解决这个问题?
编译代码
\documentclass[margin=1cm]{standalone}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{calc}
\newcommand{\logLogSlopeTriangle}[9]
{
% #1. Relative offset in x direction.
% #2. Width in x direction, so xA-xB.
% #3. Relative offset in y direction.
% #4. Slope d(y)/d(log10(x)).
% #5. Plot options.
% #6. xmin.
% #7. xmax.
% #8. ymin.
% #9. ymax.
\pgfplotsextra
{
% Calculate auxilliary quantities.
\pgfmathsetmacro{\xA}{#6^(1-#1)*#7^#1}
\pgfmathsetmacro{\yA}{#8^(1-#3)*#9^#3}
\pgfmathsetmacro{\xB}{#6^(1-(#1-#2))*#7^(#1-#2)}
\pgfmathsetmacro{\yB}{\yA}
\pgfmathsetmacro{\xC}{\xA}
\pgfmathsetmacro{\yC}{\yA/(\xB^#4)*\xA^#4}
% Define coordinates for \draw.
\coordinate (A) at (axis cs:\xA,\yA);
\coordinate (B) at (axis cs:\xB,\yB);
\coordinate (C) at (axis cs:\xC,\yC);
% Draw slope triangle.
\draw[#5] (A)-- node[pos=0.5,anchor=north] {1}
(B)--
(C)-- node[pos=0.5,anchor=west] {#4}
cycle;
}
}
\begin{document}
\begin{tikzpicture}
\begin{loglogaxis}
[
xmin=10^1, % WHAT IF I DON'T USE THIS?
xmax=10^4, % WHAT IF I DON'T USE THIS?
xlabel=$x$,
ymin=10^0.5, % WHAT IF I DON'T USE THIS?
ymax=10^4, % WHAT IF I DON'T USE THIS?
ylabel style={rotate=-90},
ylabel=$y$,
grid=major,
clip=false
]
\addplot[blue,line width=1pt,domain=10^1:10^4] {sqrt(x)};
\addplot[red,line width=1pt,domain=10^1:10^4] {x};
%\pgfplotsextra
%{
\pgfkeysgetvalue{/pgfplots/xmin}{\xmin}
\pgfkeysgetvalue{/pgfplots/xmax}{\xmax}
\pgfkeysgetvalue{/pgfplots/ymin}{\ymin}
\pgfkeysgetvalue{/pgfplots/ymax}{\ymax}
%}
\logLogSlopeTriangle{0.9}{0.1}{0.1}{1/2}{blue}{\xmin}{\xmax}{\ymin}{\ymax};
\logLogSlopeTriangle{0.75}{0.1}{0.1}{1}{red}{\xmin}{\xmax}{\ymin}{\ymax};
\end{loglogaxis}
\end{tikzpicture}
\end{document}
我得到了想要的结果
如果我不想在轴选项中明确指定轴限制,请\pgfplotsextra
使用未明确设置时轴限制的键名称应该提供一个解决方案。
因此编译代码
\documentclass[margin=1cm]{standalone}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{calc}
\newcommand{\logLogSlopeTriangle}[9]
{
% #1. Relative offset in x direction.
% #2. Width in x direction, so xA-xB.
% #3. Relative offset in y direction.
% #4. Slope d(y)/d(log10(x)).
% #5. Plot options.
% #6. xmin.
% #7. xmax.
% #8. ymin.
% #9. ymax.
\pgfplotsextra
{
% Calculate auxilliary quantities.
\pgfmathsetmacro{\xA}{#6^(1-#1)*#7^#1}
\pgfmathsetmacro{\yA}{#8^(1-#3)*#9^#3}
\pgfmathsetmacro{\xB}{#6^(1-(#1-#2))*#7^(#1-#2)}
\pgfmathsetmacro{\yB}{\yA}
\pgfmathsetmacro{\xC}{\xA}
\pgfmathsetmacro{\yC}{\yA/(\xB^#4)*\xA^#4}
% Define coordinates for \draw.
\coordinate (A) at (axis cs:\xA,\yA);
\coordinate (B) at (axis cs:\xB,\yB);
\coordinate (C) at (axis cs:\xC,\yC);
% Draw slope triangle.
\draw[#5] (A)-- node[pos=0.5,anchor=north] {1}
(B)--
(C)-- node[pos=0.5,anchor=west] {#4}
cycle;
}
}
\begin{document}
\begin{tikzpicture}
\begin{loglogaxis}
[
%xmin=10^1, % WHAT IF I DON'T USE THIS?
%xmax=10^4, % WHAT IF I DON'T USE THIS?
xlabel=$x$,
%ymin=10^0.5, % WHAT IF I DON'T USE THIS?
%ymax=10^4, % WHAT IF I DON'T USE THIS?
ylabel style={rotate=-90},
ylabel=$y$,
grid=major,
clip=false
]
\addplot[blue,line width=1pt,domain=10^1:10^4] {sqrt(x)};
\addplot[red,line width=1pt,domain=10^1:10^4] {x};
\pgfplotsextra
{
\pgfkeysgetvalue{/pgfplots/xmin}{\xmin}
\pgfkeysgetvalue{/pgfplots/xmax}{\xmax}
\pgfkeysgetvalue{/pgfplots/ymin}{\ymin}
\pgfkeysgetvalue{/pgfplots/ymax}{\ymax}
}
\logLogSlopeTriangle{0.9}{0.1}{0.1}{1/2}{blue}{\xmin}{\xmax}{\ymin}{\ymax};
\logLogSlopeTriangle{0.75}{0.1}{0.1}{1}{red}{\xmin}{\xmax}{\ymin}{\ymax};
\end{loglogaxis}
\end{tikzpicture}
\end{document}
结果是
。如您所见,三角形的位置不对。我该如何修复?
答案1
这与其说是一个解决方案,不如说是一个演示。右下角是没有使用 \pgfplotsextra 计算的 (\xmin,\xmax,\ymin,\ymax),右上角是使用 \pgfplotsextra 计算的。使用计算器可以显示 e^\xmin=5 和 e^\xmax=20,000,它们对应于轴限值。
\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{loglogaxis}
[
%xmin=10^1, % WHAT IF I DON'T USE THIS?
%xmax=10^4, % WHAT IF I DON'T USE THIS?
xlabel=$x$,
%ymin=10^0.5, % WHAT IF I DON'T USE THIS?
%ymax=10^4, % WHAT IF I DON'T USE THIS?
ylabel style={rotate=-90},
ylabel=$y$,
grid=major,
clip=false
]
\addplot[blue,line width=1pt,domain=10^1:10^4] {sqrt(x)};
\addplot[red,line width=1pt,domain=10^1:10^4] {x};
\pgfkeysgetvalue{/pgfplots/xmin}{\xmin}
\pgfkeysgetvalue{/pgfplots/xmax}{\xmax}
\pgfkeysgetvalue{/pgfplots/ymin}{\ymin}
\pgfkeysgetvalue{/pgfplots/ymax}{\ymax}
\node[above left] at (rel axis cs: 1,0) {(\xmin, \xmax, \ymin, \ymax)};
\pgfplotsextra
{
\pgfkeysgetvalue{/pgfplots/xmin}{\xmin}
\pgfkeysgetvalue{/pgfplots/xmax}{\xmax}
\pgfkeysgetvalue{/pgfplots/ymin}{\ymin}
\pgfkeysgetvalue{/pgfplots/ymax}{\ymax}
\node[below left] at (rel axis cs: 1,1) {(\xmin, \xmax, \ymin, \ymax)};
}
\end{loglogaxis}
\end{tikzpicture}
\end{document}
答案2
正确的代码似乎是
\documentclass[margin=1cm]{standalone}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{calc}
\newcommand{\logLogSlopeTriangle}[5]
{
% #1. Relative offset in x direction.
% #2. Width in x direction, so xA-xB.
% #3. Relative offset in y direction.
% #4. Slope d(y)/d(log10(x)).
% #5. Plot options.
\pgfplotsextra
{
\pgfkeysgetvalue{/pgfplots/xmin}{\xmin}
\pgfkeysgetvalue{/pgfplots/xmax}{\xmax}
\pgfkeysgetvalue{/pgfplots/ymin}{\ymin}
\pgfkeysgetvalue{/pgfplots/ymax}{\ymax}
% Calculate auxilliary quantities.
\pgfmathsetmacro{\xA}{(exp(\xmin))^(1-#1)*(exp(\xmax))^#1}
\pgfmathsetmacro{\yA}{(exp(\ymin))^(1-#3)*(exp(\ymax))^#3}
\pgfmathsetmacro{\xB}{(exp(\xmin))^(1-(#1-#2))*(exp(\xmax))^(#1-#2)}
\pgfmathsetmacro{\yB}{\yA}
\pgfmathsetmacro{\xC}{\xA}
\pgfmathsetmacro{\yC}{\yA/(\xB^#4)*\xA^#4}
% Define coordinates for \draw.
\coordinate (A) at (axis cs:\xA,\yA);
\coordinate (B) at (axis cs:\xB,\yB);
\coordinate (C) at (axis cs:\xC,\yC);
% Draw slope triangle.
\draw[#5] (A)-- node[pos=0.5,anchor=north] {1}
(B)--
(C)-- node[pos=0.5,anchor=west] {#4}
cycle;
}
}
\begin{document}
\begin{tikzpicture}
\begin{loglogaxis}
[
xlabel=$x$,
ylabel style={rotate=-90},
ylabel=$y$,
grid=major,
clip=false
]
\addplot[blue,line width=1pt,domain=10^1:10^2] {sqrt(x)};
\addplot[red,line width=1pt,domain=10^1:10^2] {x};
\logLogSlopeTriangle{0.9}{0.1}{0.1}{0.5}{blue};
\logLogSlopeTriangle{0.75}{0.1}{0.1}{1}{red};
\end{loglogaxis}
\end{tikzpicture}
\end{document}
,其中我将其替换\xmin
为(exp(\xmin))
、、、和。\xmax
(exp(\xmax))
\ymin
(exp(\ymin))
\ymax
(exp(\ymax))
显然,使用\pgfplotsextra
给出了轴限制,log(...)
因此exp(...)
需要应用它来获得正确的局部坐标。
结果如下:
答案3
\pgfplotsextra
大致是pgfplots
TikZ/PGF 等效的命令\pgfextra
。
这里有两件事相互作用。首先,在路径绘制执行方面,pgfplots
TikZ 不是,这是有充分理由的。因为它必须基于绘制的实体创建一个轴,以便路径被轴限制紧密封装,刻度、网格线和刻度标签会自动计算等等。为了做到这一点,pgfplots 会收集所有可能绘制的东西,直到轴环境完成。
然后开始评估最大值、极限等,并准备轴,然后才开始将收集的项目作为绘图命令传输到 PGF。所以最后你看到的是一堆在 TikZ 图片中绘制的 PGF 路径。
然而,TikZ 没有这种行为。当您发出路径命令时,它会立即发送相关的驱动程序命令,并命令 PDF 特殊命令。如果\pgfextra
需要推迟当前路径构建,请执行参数\pgfextra
(例如更改某些定义或执行和定义某些计算),然后恢复路径构建。
如果pgfplots
需要将原生 TikZ 绘图命令与 pgfplots 的绘图对象一起传输,以便在轴集合完成后也执行它们。例如,在轴完成之前未设置 值,并且您可能会读取默认值(如果不是零)xmin
。xmax
本质上这就是为什么需要使用\pgfplotsextra
其他方法,因为您已经体验过所有数字和维度等都未启动,但解析仍然完成,pgfplots
因此您会得到奇怪形状的路径(我认为这里它们都是 log()版本而不是实际单位但没有检查)。
需要注意的是,当遇到 TikZ 路径命令时pgfplots
,它通常足够聪明,可以自动执行\pgfplotsextra
添加。但如果需要在轴完成后计算额外的数据,它就无法提供进一步的帮助。
对于您来说,有更简单的替代方案:
如果绘图大部分是线性的,则将坐标放在绘图上并执行所需的任何操作
如果您有复杂的情节,需要切线和其他复杂因素,请使用装饰。
对于第一种情况举例:
\documentclass[margin=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\begin{document}
\begin{tikzpicture}
\begin{loglogaxis}[
xlabel=$x$,
ylabel style={rotate=-90},
ylabel=$y$,
grid=major,
]
\addplot[blue,line width=1pt,domain=10^1:10^4] {sqrt(x)}
coordinate[pos=0.50] (a)
coordinate[pos=0.75] (b);
\draw[blue] (a) -| (b)
node[pos=0.25,below] {1}
node[pos=0.75,right] {2}; % Or whatever complicated label
\end{loglogaxis}
\end{tikzpicture}
\end{document}