![TikZ/pgfplots - 如何正确分层绘制网格线?](https://linux22.com/image/454424/TikZ%2Fpgfplots%20-%20%E5%A6%82%E4%BD%95%E6%AD%A3%E7%A1%AE%E5%88%86%E5%B1%82%E7%BB%98%E5%88%B6%E7%BD%91%E6%A0%BC%E7%BA%BF%EF%BC%9F.png)
我正在修改图表。第三方要求我使用 pgfplots 来做这件事。
(因此,我在这件事上遇到问题的真正原因可以从我的社交技巧中看出:我让自己陷入了一种应该避免的境地:在没有深入了解所要使用的工具的情况下,就参与快速而完美地组合某些东西。需要一些时间来熟悉 TikZ 和 pgfplots,这不能怪开发人员。
我很感谢这些有用的答案,也感谢那些帮助我的人所表现出的善良和直率。)
到目前为止,我已经拼凑了下面的代码。
我想优化我目前拥有的插图。
经过两天多的工作(大部分时间都在搜索有关 pgfplots 用法的正确信息),我仍然有以下问题:
- 如何让“次要网格”的(细、浅)网格线位于“主要网格”的较粗/较深网格线下方,而不是位于其上方?对于额外的 x 刻度和额外的 y 刻度,不仅次要网格的水平线而且垂直线也位于主要网格的线上方?
- 如何使刻度与轴的颜色相同?
- 如何提取有关刻度的线条样式/颜色等的数据,以便数据也可以在轴环境之外使用?
- 是否有更简单的方法来标记坐标原点,如图所示,并且它也可以在轴环境中使用?
- 如何让图表不粘在轴线上?
\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
改编
有很多问题。我解决了其中一些:
- 再次手动绘制主要网格
我进行设置\draw[xstep=1,ystep=1,lightgray,thin] (0,0) grid (15.5,3.5);
xmin = 0.01, ymin = 0.01
以便可以拥有xtick
并ytick
开始0
,因此不需要再次在上面绘制额外的刻度。 - 使蜱虫变黑
\pgfplotsset{every tick/.append style={color=black}}
- 和 ...
- 也许可以使用 Torbjørn T. 的评论(我还没有实现那个)
- “蓝色图表不应与黑色轴重叠” – 我使用了回答作者: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}