TikZ/pgfplots - 如何正确分层绘制网格线?

TikZ/pgfplots - 如何正确分层绘制网格线?

我正在修改图表。第三方要求我使用 pgfplots 来做这件事。

(因此,我在这件事上遇到问题的真正原因可以从我的社交技巧中看出:我让自己陷入了一种应该避免的境地:在没有深入了解所要使用的工具的情况下,就参与快速而完美地组合某些东西。需要一些时间来熟悉 TikZ 和 pgfplots,这不能怪开发人员。

我很感谢这些有用的答案,也感谢那些帮助我的人所表现出的善良和直率。)

到目前为止,我已经拼凑了下面的代码。

我想优化我目前拥有的插图。
经过两天多的工作(大部分时间都在搜索有关 pgfplots 用法的正确信息),我仍然有以下问题:

  1. 如何让“次要网格”的(细、浅)网格线位于“主要网格”的较粗/较深网格线下方,而不是位于其上方?对于额外的 x 刻度和额外的 y 刻度,不仅次要网格的水平线而且垂直线也位于主要网格的线上方?
  2. 如何使刻度与轴的颜色相同?
  3. 如何提取有关刻度的线条样式/颜色等的数据,以便数据也可以在轴环境之外使用?
  4. 是否有更简单的方法来标记坐标原点,如图所示,并且它也可以在轴环境中使用?
  5. 如何让图表不粘在轴线上?
\documentclass[tikz,border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat = newest} % <- Without this strangely the axis label is not placed 
                              %    correctly; it took four hours to figure this out.

\begin{document}

\begin{tikzpicture}[x=1cm, y=1cm]
% Why are there no pgf-keys whose values could be retrieved for having the length of
% the x- and the y-unit-vector.
\path(1,1);\pgfgetlastxy{\Ax}{\Ay}%
\begin{axis}[%
  x=\Ax, y=\Ay,
  axis y line = left,
  axis x line = bottom,
  xtick pos=bottom,
  ytick pos=left,
  y axis line style = {->},
  x axis line style = {->},
  xtick distance = 1, 
  ytick distance = 1, 
  tick align=outside,
  minor tick style={draw=none},
  xlabel style={at={(rel axis cs:1,0)}}, xlabel = {\(x\)},
  ylabel style={at={(rel axis cs:0,1)},rotate=-90},  ylabel = {\(y\)},
  grid=both, 
    minor grid style={very thin, lightgray!25}, 
    minor tick num = 9, 
    major grid style={thin},
  xmin = 0, xmax = 15.5, ymin = 0, ymax = 3.5,
  xtick = {1,...,15.5},
  ytick = {1,...,3.5},
  extra x ticks={0,1},
  extra x tick labels={},
  extra x tick style={grid=minor, major tick length=0pt},
  extra y ticks={0,1},
  extra y tick labels={},
  extra y tick style={grid=minor, major tick length=0pt},
]%
%  It seems drawing outside the area specified by xmin/xmax/ymin/ymax
%  is not (easily) possible from inside the axis environment, so let's
%  calculate the components of the vector of the origin tick now and
%  save them to macros for usage outside the axis environment.
%  Probably the line-style of major ticks should be saved for usage
%  outside also but I don't want to spend a week on finding out how
%  to do so.
%\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/x}}%
%\global\let\scratchx=\pgfmathresult
%\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/y}}%
%\global\let\scratchy=\pgfmathresult
\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/x}/sqrt(2)}%
\global\let\scratchx=\pgfmathresult
\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/y}/sqrt(2)}%
\global\let\scratchy=\pgfmathresult
%
\addplot[
  domain = 0:15.5,%
  samples = 2,% <- I suppose for a straight line more samples are not needed
  smooth, thick, blue
]{x/5} node[above,pos=0.5] {\vbox{\hbox{\(f(x)=\frac{x}{5}\)}\kern.1\dimexpr\Ay\relax}};
\end{axis}
% Draw the origin:
%\draw[very thin] (0,0)--(\scratchx,\scratchy) node [anchor=north east]{\(\mathrm{O}\)};
\draw[very thin] (0,0)--(\scratchx,\scratchy);
\coordinate (\scratchx,\scratchy) node [anchor=north east]{\(\mathrm{O}\)};
\end{tikzpicture}
\end{document}

整个图表:

在此处输入图片描述

放大左下角,以便人们可以看到我的问题:
 

在此处输入图片描述



感谢 dexteritas 和 Torbjørn T.,我现在整理出了一些可以在环境中运行的东西axis,这使得问题 3 变得过时并且还解决了所有其他问题:

以下是代码:

\documentclass[tikz,border=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows}
\pgfplotsset{compat = newest} % <- Without this the axis label is not placed correctly.
\begin{document}
\begin{tikzpicture}[x=1cm, y=1cm]
% Why are there no pgf-keys whose values could be retrieved for having the length of
% the x- and the y-unit-vector?
\path(1,1);\pgfgetlastxy{\Ax}{\Ay}%
\begin{axis}[%
  %
  % General settings:
  %
  % - Make x and y the same as that of the surrounding tikzpicture environment:
  %
  x=\Ax, y=\Ay,
  %
  % - When the end of the axis environment is reached redraw the axes to ensure
  %   they are not overlapped by a graph or by components of the grid:
  %
  after end axis/.append code={
      \pgfplotsset{
          axis line style=opaque,
          ticklabel style=opaque,
          tick style=opaque,
          grid=none
      }
      \csname pgfplots@draw@axis\endcsname
  },
  %
  % - Make it possible to draw outside the area denoted by xmin/xmax/ymin/ymax:
  %
  clip mode=individual,
  %
  % Appearance of the axes:
  %
  axis y line = left,
  axis x line = bottom,
  y axis line style = {->, >=stealth'},
  x axis line style = {->, >=stealth'},
  xlabel style={at={(rel axis cs:1,0)}}, xlabel = {\(x\)},
  ylabel style={at={(rel axis cs:0,1)},rotate=-90},  ylabel = {\(y\)},
  %
  % - range of the axes:
  %
  xmin = 0, xmax = 15.5, ymin = 0, ymax = 3.5,
  %
  % Appearance of the ticks on the axes and the tick labels:
  %
  xtick pos=bottom,
  ytick pos=left,
  xtick distance = 1, 
  ytick distance = 1, 
  tick align=outside,
  major tick style={thin, black},
  minor tick style={very thin, black},
  minor tick num = 1, 
  %
  % As the origin needs extra treatment labels of major ticks shall begin with 1:
  %
  xtick = {1,...,15},
  ytick = {1,...,3},
  %
  % Draw extra minor ticks at x=0.5 and y=0.5; the pgfplots-manual says that
  % all extra ticks are considered major ticks, so use extra x tick style/
  % extra y tick style for assigning major ticks the parameters of minor ticks
  % and then draw them without labels:
  %
  extra x tick style={major tick length=\pgfkeysvalueof{/pgfplots/minor tick length}, major tick style={very thin, black}},
  extra y tick style={major tick length=\pgfkeysvalueof{/pgfplots/minor tick length}, major tick style={very thin, black}},
  extra x ticks={0.5},
  extra y ticks={0.5},
  extra x tick labels={},
  extra y tick labels={},
  grid=none, 
]%
%
% Draw the grids:
%
\draw[xstep=0.1,ystep=0.1,lightgray!25,ultra thin] (0,0) grid (15.5,3.5); 
\draw[xstep=0.5,ystep=0.5,lightgray!66,very thin] (0,0) grid (15.5,3.5);
\draw[xstep=1,ystep=1,lightgray,thin] (0,0) grid (15.5,3.5);
%
% Draw the plot(s):
%  
% - The slope of the following plot is 1/5. So let's rotate the node atan(1/5).
\pgfmathparse{atan(1/5)}\let\scratch\pgfmathresult
\addplot[
  domain = 0:15.5,%
  samples = 2,% <- I suppose for a straight line more samples are not needed
  smooth, thick, blue
]{x/5} node[above,pos=0.5,rotate={\scratch}] {\footnotesize\(f(x)=\frac{x}{5}\)};
%
% Draw the origin:
%
%\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/x}}%
%\let\scratchx=\pgfmathresult
%\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/y}}%
%\let\scratchy=\pgfmathresult
%\draw[thin] (0,0)--(\scratchx,\scratchy) node [anchor=north east]{\(\mathrm{O}\)};
\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/x}/sqrt(2)}%
\let\scratchx=\pgfmathresult
\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/y}/sqrt(2)}%
\let\scratchy=\pgfmathresult
\draw[thin] (0,0)--(\scratchx,\scratchy);
\coordinate (\scratchx,\scratchy) node [anchor=north east]{\(\mathrm{O}\)};
%
\end{axis}
\end{tikzpicture}
\end{document}

以下是整个情节:

在此处输入图片描述

此处为放大图:

在此处输入图片描述

答案1

改编

有很多问题。我解决了其中一些:

  1. 再次手动绘制主要网格
    \draw[xstep=1,ystep=1,lightgray,thin] (0,0) grid (15.5,3.5);
    
    我进行设置xmin = 0.01, ymin = 0.01以便可以拥有xtickytick开始0,因此不需要再次在上面绘制额外的刻度。
  2. 使蜱虫变黑
    \pgfplotsset{every tick/.append style={color=black}}
    
  3. 和 ...
  4. 也许可以使用 Torbjørn T. 的评论(我还没有实现那个)
  5. “蓝色图表不应与黑色轴重叠” – 我使用了回答作者:Jaketikz/pgfplots 高级 z 顺序轴/网格
    after end axis/.append code={
        \pgfplotsset{
            axis line style=opaque,
            ticklabel style=opaque,
            tick style=opaque,
            grid=none
        }
        \pgfplotsdrawaxis
    },
    

结果

在此处输入图片描述

代码

\documentclass[tikz,border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat = newest} % <- Without this strangely the axis label is not placed 
                              %    correctly; it took four hours to figure this out.

\begin{document}

\makeatletter \newcommand{\pgfplotsdrawaxis}{\pgfplots@draw@axis} \makeatother

\pgfplotsset{
    every tick/.append style={color=black},
    after end axis/.append code={
        \pgfplotsset{
            axis line style=opaque,
            ticklabel style=opaque,
            tick style=opaque,
            grid=none
        }
        \pgfplotsdrawaxis
    },
} % applies to major and minor ticks,

\begin{tikzpicture}[x=1cm, y=1cm]
% Why are there no pgf-keys whose values could be retrieved for having the length of
% the x- and the y-unit-vector.
\path(1,1);\pgfgetlastxy{\Ax}{\Ay}%
\begin{axis}[%
  x=\Ax, y=\Ay,
  axis y line = left,
  axis x line = bottom,
  xtick pos=bottom,
  ytick pos=left,
  y axis line style = {->},
  x axis line style = {->},
  xtick distance = 1, 
  ytick distance = 1, 
  tick align=outside,
  minor tick style={draw=none},
  xlabel style={at={(rel axis cs:1,0)}}, xlabel = {\(x\)},
  ylabel style={at={(rel axis cs:0,1)},rotate=-90},  ylabel = {\(y\)},
  grid=both, 
    minor grid style={very thin, lightgray!25}, 
    minor tick num = 9, 
    major grid style={thin},
  xmin = 0.01, xmax = 15.5, ymin = 0.01, ymax = 3.5,
  xtick = {0,...,15.5},
  ytick = {0,...,3.5},
]%
%  It seems drawing outside the area specified by xmin/xmax/ymin/ymax
%  is not (easily) possible from inside the axis environment, so let's
%  calculate the components of the vector of the origin tick now and
%  save them to macros for usage outside the axis environment.
%  Probably the line-style of major ticks should be saved for usage
%  outside also but I don't want to spend a week on finding out how
%  to do so.
%\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/x}}%
%\global\let\scratchx=\pgfmathresult
%\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/y}}%
%\global\let\scratchy=\pgfmathresult
\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/x}/sqrt(2)}%
\global\let\scratchx=\pgfmathresult
\pgfmathparse{-\pgfkeysvalueof{/pgfplots/major tick length}/\pgfkeysvalueof{/pgfplots/y}/sqrt(2)}%
\global\let\scratchy=\pgfmathresult
%
\draw[xstep=1,ystep=1,lightgray,thin] (0,0) grid (15.5,3.5); % override with major grid again
%
\addplot[
  domain = 0:15.5,%
  samples = 2,% <- I suppose for a straight line more samples are not needed
  smooth, thick, blue
]{x/5} node[above,pos=0.5] {\vbox{\hbox{\(f(x)=\frac{x}{5}\)}\kern.1\dimexpr\Ay\relax}};
\end{axis}
% Draw the origin:
%\draw[very thin] (0,0)--(\scratchx,\scratchy) node [anchor=north east]{\(\mathrm{O}\)};
\draw[very thin] (0,0)--(\scratchx,\scratchy);
\coordinate (\scratchx,\scratchy) node [anchor=north east]{\(\mathrm{O}\)};
\end{tikzpicture}
\end{document}

相关内容