我使用了这篇文章中提到的 TUGBoat 第 34 期中的优秀代码带有 pgfplots 的 Tufte 类轴一直都很开心,直到我尝试将它与对数轴一起使用。问题似乎是存储在\pgfplots@data@xmin
等中的值是对数的。
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
% automatically save the min and max value of the data
% this part is crucial for me since I do not want to find the min and max values manually in a large data file.
\makeatletter
\def\pgfplotsdataxmin{\pgfplots@data@xmin}
\def\pgfplotsdataxmax{\pgfplots@data@xmax}
\def\pgfplotsdataymin{\pgfplots@data@ymin}
\def\pgfplotsdataymax{\pgfplots@data@ymax}
\makeatother
% This adds the min and max values found above as extra ticks
\pgfplotsset{tufte extra ticks/.style={
extra x ticks={
\pgfplotsdataxmin,
\pgfplotsdataxmax
},
extra y ticks={
\pgfplotsdataymin,
\pgfplotsdataymax
},
}}
\pgfplotsset{
range frame/.style={
tick align=outside,
axis line style={opacity=0},
after end axis/.code={
\draw ({rel axis cs:0,0}-|{axis cs:\pgfplotsdataxmin,0}) -- ({rel axis cs:0,0}-|{axis cs:\pgfplotsdataxmax,0});
\draw ({rel axis cs:0,0}|-{axis cs:0,\pgfplotsdataymin}) -- ({rel axis cs:0,0}|-{axis cs:0,\pgfplotsdataymax});
}
}
}
\begin{tikzpicture}
\begin{axis}[
range frame,
xlabel={$L$ [H]},
ylabel={$\hat{I}_{DM}$ [A]},
axis lines*=left,
ymin=0.41,
ytick={0.7,0.9,...,1.5},
xtick={1.5e-3,2e-3,2.5e-3},
tufte extra ticks,
xmode=log, % <- comment this out to get a working example
]
\addplot +[black, mark options=fill=black] coordinates {(948e-6,1.61981) (1.5e-3,1.02377) (2e-3,0.769047) (2.5e-3,0.614994) (3.2e-3,0.503511)};
\end{axis}
\end{tikzpicture}
\end{document}
如果一个或两个轴都处于对数模式,有没有办法解决这个问题?
编辑: tufte extra ticks
目的是为每个轴的最小值和最大值创建一个刻度,如下图所示。
答案1
正如前面提到的对该问题的评论-- 在 PGFPlots v1.13 中,关键axis line shift
,可以轻松生成类似 Tufte 的轴(请查看手册第 255 页第 4.9.10 节)。但是,v1.13 在移动轴时不考虑轴标签等。这已在PGFPlots 错误追踪器并已在 2016-08-10 发布的 v1.14 中修复。
说它仍然是将xmin
和xmax
值作为标签添加到轴的问题。我认为目前没有其他方法,只能手动将xmin
和xmax
值作为选项添加到轴,然后您可以使用命令将它们添加为xticks
或。给出的答案支持这一点extra x ticks
\pgfkeysvalueof
这里。
(不过有点奇怪的是,当给定xmin=9e-4
存储的值时-7.01
时,可以通过添加的灰色节点看到。Jake 指出评论这是因为数字总是以自然对数形式存储,所以exp(-7.01)=0.0009
。这解释了为什么数字没有显示为10^(-3.05)=0.0009
。)
\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
% use Tufte like axis
axis line shift=10pt,
% because of a bug in v1.13 one has to shift the labels, etc.
% by hand. This is not necessary in v1.14!
xlabel style={
yshift=-10pt,
},
ylabel style={
yshift=10pt,
},
%
% to set some extra ticks at the beginning and the end of the
% axis you have to give the values explicitly
xmin=9e-4,
xmax=4e-3,
% now you can add them as extra ticks
extra x ticks={
\pgfkeysvalueof{/pgfplots/xmin},
\pgfkeysvalueof{/pgfplots/xmax}
},
%
% % if you want to change the tick label style to `i \cdot 10^j'
% % (where `i' has to be an integer, e.g. $2 \cdot 10^{-3}$)
% xticklabel style={
% log identify minor tick positions=true,
% },
%
xlabel={$L$ [H]},
ylabel={$\hat{I}_{DM}$ [A]},
axis lines*=left,
%
ymin=0.41,
ytick={0.7,0.9,...,1.5},
xtick={1.5e-3,2e-3,2.5e-3},
%
xmode=log,
]
\addplot +[black, mark options=fill=black] coordinates {(948e-6,1.61981) (1.5e-3,1.02377) (2e-3,0.769047) (2.5e-3,0.614994) (3.2e-3,0.503511)};
% for debugging show the value of `xmin'
% (--> why does it show a value of -7.01?)
\node [fill=black!25,anchor=south west] at (rel axis cs:0,0)
{xmin = \pgfmathprintnumber{\pgfkeysvalueof{/pgfplots/xmin}}};
\end{axis}
\end{tikzpicture}
\end{document}
从表中提取最小值和最大值的解决方案
要“提取”数据的最小值和最大值,您可以将它们放入表中,然后使用pgfplotstable
包对数据进行排序和提取。
有关更多详细信息,请查看代码中的注释。
% first put the data to an external file or a table,
% so it can be handled by the `pgfplotstable' package
\begin{filecontents}{data.txt}
948e-6 1.61981
1.5e-3 1.02377
2e-3 0.769047
2.5e-3 0.614994
3.2e-3 0.503511
\end{filecontents}
\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usetikzlibrary{
fpu,
positioning, % <-- for debugging nodes only
}
\pgfplotsset{
compat=1.13,
}
\begin{document}
\begin{tikzpicture}
% to be sure that no numbers are interpreted as zero, activate `fpu'
% library
\tikzset{
fpu=true,
}
%%% find `xmin' and `xmax'
% for that first sort the table after the x values
\pgfplotstablesort{\SortedTable}{data.txt}
\tikzset{
fpu=false,
}
% then one can directly extract `xmin'
\pgfplotstablegetelem{0}{[index] 0}\of\SortedTable
\let\xmin=\pgfplotsretval
%% now extract `xmax'
% for that we first need to extract the number of rows in the table
\pgfplotstablegetrowsof{\SortedTable}
\pgfmathsetmacro{\NoOfRows}{\pgfplotsretval-1}
% then we can extract the last entry in the sorted table
\pgfplotstablegetelem{\NoOfRows}{[index] 0}\of\SortedTable
\let\xmax=\pgfplotsretval
\begin{axis}[
% use Tufte like axis
axis line shift=10pt,
% because of a bug in v1.13 one has to shift the labels, etc.
% by hand
xlabel style={
yshift=-10pt,
},
ylabel style={
yshift=10pt,
},
%
% add the extra ticks from the extracted data
extra x ticks={
\xmin,
\xmax
},
% just to make sure these are the extra ticks, draw them red
extra x tick style={
text=red,
},
%
% % if you want to change the tick label style to `i \cdot 10^j'
% % (where `i' has to be an integer, e.g. $2 \cdot 10^{-3}$)
% xticklabel style={
% log identify minor tick positions=true,
% },
%
xlabel={$L$ [H]},
ylabel={$\hat{I}_{DM}$ [A]},
axis lines*=left,
%
ymin=0.41,
ytick={0.7,0.9,...,1.5},
xtick={1.5e-3,2e-3,2.5e-3},
%
xmode=log,
]
\addplot +[black, mark options=fill=black] table {data.txt};
% for debugging show the value of `xmax'
\node [fill=black!25,anchor=south west] (a) at (rel axis cs:0,0)
{xmax = \pgfmathprintnumber{\xmax}};
\node [fill=black!25,above=1pt of a.north west,anchor=south west]
{Rows = \pgfmathprintnumber{\NoOfRows}};
\end{axis}
\end{tikzpicture}
\end{document}