有没有办法让tikz
一个 LaTeX 文档中的所有 -plot 的 s 之间的距离相同plot mark
,即标记之间的距离应该与样本大小无关。如果这种变化不会干扰图例,比如改变标记的位置等,那就太好了legend
。谢谢。
编辑:不幸的是,所有数据点(不是在小示例中,而是对于真实数据)的距离并不相同,因此如果我能以厘米为单位定义标记之间的距离就好了。
\documentclass[tikz,border=1mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{decorations.markings}
\pgfplotsset{compat=1.11}
%\tikzset{mark/.style={
% decoration={
% markings,
% mark= between positions 0 and 1 step 5mm with
% {
% %\node[circle,inner sep=2pt,fill=blue]{};
% },
% },
% postaction={decorate}
% }
%}
\begin{document}
\begin{tikzpicture}
\begin{axis}[]
\addplot[
blue,
domain=0:3,
samples=100,
mark=*
]
{exp(x)};
\addlegendentry{exp(x)};
\addplot[
red,
domain=0:3,
samples=20,
mark=diamond
]
{4*x};
\addlegendentry{4x};
\end{axis}
\end{tikzpicture}
\end{document}
编辑:是否可以将诸如mark size
或之类的选项传递给 tikz mark options={solid}
?
\addplot [color=black,loosely dotted,line width=1.5pt, mark=*,mark size=3pt, mark=diamond,mark options={solid}]
edit2:我知道如何solid
在图例中设置标记,但如何在情节中做同样的事情?有什么想法可以solid
在实际情节中获取情节标记吗?
\tikzset{
nomorepostactions/.code={\let\tikz@postactions=\pgfutil@empty},
mymark/.style={decoration={markings,
mark= between positions 0 and 1 step (1/11)*\pgfdecoratedpathlength with{%
\pgfuseplotmark{#1},%
},
},
postaction={decorate},
/pgfplots/legend image post style={mark=#1,every path/.append style={nomorepostactions}},
},
every mark/.append style={solid,mark size=3},
}
答案1
与 Harish 的答案类似,但无需绘制两次。您基本上需要停止后操作到达图例图片,因为这是导致标记位置奇怪的原因。您可以使用我们的好答案来做到这一点对 TikZ 中的每个路径应用后动作
\documentclass[]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\usetikzlibrary{decorations.markings}
\makeatletter
\tikzset{
nomorepostactions/.code={\let\tikz@postactions=\pgfutil@empty},
mymark/.style 2 args={decoration={markings,
mark= between positions 0 and 1 step (1/11)*\pgfdecoratedpathlength with{%
\tikzset{#2,every mark}\tikz@options
\pgfuseplotmark{#1}%
},
},
postaction={decorate},
/pgfplots/legend image post style={
mark=#1,mark options={#2},every path/.append style={nomorepostactions}
},
},
}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{axis}[legend style={at={(0.5,0.95)}, anchor=north},
legend entries={$\exp(x)$,$10\sin(5x)$},
]
\addplot[blue,dashed, domain=0:3,samples=15,mymark={o}{solid}]{exp(x)};
\addplot[red,domain=0:3, dashdotted,samples=200,
mymark={diamond*}{draw=black,fill=yellow,solid}]{10*sin(deg(5*x))};
\end{axis}
\end{tikzpicture}
\end{document}
您还可以通过将总路径长度除以一个固定数字来添加另一个参数,以表示您想要有多少个标记。这里我选择了 11。(用距离代替可能是您希望的,但我在这里将其作为替代方案)
标记距离为 1 cm
编辑对于添加的样式问题,代码现在提供
答案2
legend image post style
Hee 是一种使用tikz的方法decorations
。我们首先定义一个装饰,然后绘制两次相同的曲线,一次只使用装饰标记,然后不使用标记。
\documentclass[tikz,border=1mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{plotmarks}
\pgfplotsset{compat=1.11}
\tikzset{mymark/.style={
decoration={
markings,
mark= between positions 0 and 1 step 5mm with
{
\pgfuseplotmark{#1};
},
},
postaction={decorate}
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[legend style={at={(0.5,0.95)}, anchor=north}]
\addplot[
blue,
domain=0:3,
samples=100,
mymark={o},
draw=none,
forget plot, %% don't consider this plot for legends
]
{exp(x)};
\addplot[
blue,
domain=0:3,
samples=100,
mark=none,smooth,
legend image post style={mark=o} %% <-----
]
{exp(x)};
\addlegendentry{exp(x)};
\addplot[
red,
domain=0:3,
samples=20,
mymark={diamond},
draw=none,
forget plot,
]
{4*x};
\addplot[
red,
domain=0:3,
samples=20,
mark=none,smooth,
legend image post style={mark=diamond}
]
{4*x};
\addlegendentry{10 sin(x)};
\end{axis}
\end{tikzpicture}
\end{document}
答案3
使用 MetaPost 完成,具有实际的正弦曲线。(图例框仍有待完成。)对于标记,它是否是您希望获得的东西?
请注意,这只是我对这里一个非常相似的问题的回答的改编:Pgfplot,到达路径上的距离时显示标记
编辑现在,饰框已在此处,并进行了一些其他 (微小) 更改。
\documentclass[border=2bp]{standalone}
\usepackage{luamplib}
\mplibsetformat{metafun}
\mplibtextextlabel{enable}
\mplibnumbersystem{double}
\begin{document}
\begin{mplibcode}
% Reimplementation of the `point .. of ..` binary operator
% somewhat bugged in the current metafun format:
% http://tug.org/pipermail/metapost/2015-March/003065.html
primarydef len on pat = % no outer ( ) .. somehow fails
(arctime if len>=0 : len else : (arclength(pat)+len) fi of pat) of pat
enddef;
% Parameters
u = 2cm; v = .3cm; pen bigdot; bigdot = pencircle scaled 3bp;
xmin = -.25; xmax = 3.25; ymin = -1; ymax = 22.5;
len = 4bp; nmarks = 20; % length and number of marks
% Function curve
vardef function(expr xmin, xmax, xstep)(text f_x) =
save x; x := xmin;
(x, f_x)
forever:
hide(x := x + xstep)
exitunless x <= xmax;
.. (x, f_x)
endfor
if x - xstep < xmax: hide(x := xmax) .. (x, f_x) fi
enddef;
% Exponential and sinusoide curve
path expcurve; expcurve = function(ceiling(xmin), floor(xmax), .1)(exp x) xyscaled (u, v);
path sincurve; sincurve = function(ceiling(xmin), floor(xmax), .1)(10sin x) xyscaled (u, v);
% Space between marks
exp_marksep = arclength expcurve / (nmarks-1);
sin_marksep = arclength sincurve / (nmarks-1);
% Cartouche management
def define_cartouche(text cartouche)(expr pos) =
picture cartouche; cartouche = nullpicture;
numeric _cnt; _cnt = 0;
def addto_cartouche (suffix cartouche)(expr wd, str) =
addto cartouche also (image(draw pos - (wd,0) -- pos;
drawdot pos - (.5wd, 0) withpen bigdot;
label.rt(str, pos) withcolor black)
yshifted -_cnt*\mpdim{\baselineskip});
_cnt := _cnt + 1;
enddef;
enddef;
beginfig(1);
define_cartouche(box)((2u, 20v));
% Curves and marks
drawoptions(withcolor blue); draw expcurve;
for i = 0 upto nmarks-1:
%drawdot point (arctime (i*exp_marksep) of expcurve) of expcurve withpen bigdot;
draw point (i*exp_marksep) on expcurve withpen bigdot;
endfor
addto_cartouche(box, .5cm, "$\exp x$");
drawoptions(withcolor red); draw sincurve;
for i = 0 upto nmarks-1:
%draw point (arctime (i*sin_marksep) of sincurve) of sincurve withpen bigdot;
draw point (i*sin_marksep) on sincurve withpen bigdot;
endfor
addto_cartouche(box, .5cm, "$10\sin x$");
% Axes and labels
drawoptions();
draw ((xmin, ymin) -- (xmax, ymin) -- (xmax, ymax) -- (xmin, ymax) -- cycle) xyscaled (u, v);
for i = 0 upto 3:
draw (u*i, ymin*v) -- (u*i, ymin*v+len);
draw (u*i, ymax*v) -- (u*i, ymax*v-len);
label.bot(decimal i, (i*u, ymin*v));
endfor;
for j = 0 step 5 until 20:
draw (xmin*u, j*v) -- (xmin*u + len, j*v);
draw (xmax*u, j*v) -- (xmax*u - len, j*v) ;
label.lft(decimal j, (xmin*u, j*v));
endfor;
draw bbox box enlarged 2bp; draw box;
endfig;
\end{mplibcode}
\end{document}
答案4
如果手动解决方案足以满足您的使用需求,您可以使用键mark repeat=<n>
仅绘制每个n标记。在这里,我为每个samples
设置添加了 1,以便事情以整数形式运行:
\documentclass[tikz,border=1mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{decorations.markings}
\pgfplotsset{compat=1.11}
\begin{document}
\begin{tikzpicture}
\begin{axis}[]
\addplot[
blue,
domain=0:3,
samples=101,
mark=*,
mark repeat=5, % calculated using (101-1)/(21-1) = 5
]
{exp(x)};
\addlegendentry{exp(x)};
\addplot[
red,
domain=0:3,
samples=21,
mark=diamond
]
{4*x};
\addlegendentry{10 sin(x)};
\end{axis}
\end{tikzpicture}
\end{document}