8

Is there a way to get for all tikz-plots in one LaTeX document the same distance between the plot marks, ie the distance between the marks should be independent of sample size. It would be really great if this change wouldn't interfere with the legend like change the position of the marker in the legend etc. Thanks.

Edit: Unfortunately the distance of all data points (not in the mini example but for the real data) is not the same therefore it would be nice if I could define distance between the marks in cm.

\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} 

edit: Is is possible to pass to tikz such options like mark size or mark options={solid} ?

 \addplot [color=black,loosely dotted,line width=1.5pt, mark=*,mark size=3pt, mark=diamond,mark options={solid}] 

edit2: I found out how I can set the marks solid in the legend but how can I do the same in for the plot? Any ideas how to get the plot marks solid in the actual plot?

\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}, } 

enter image description here

1

4 Answers 4

12

Similar to Harish's answer but removes the need to plot twice. You basically need to stop the postaction reaching to the legend pictures because that is what is causing the funky mark placement. And that you can do with our good ol' answer to Applying a postaction to every path in 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} 

You can also add yet another parameter for how many marker you want to have by dividing the total path length to a fixed number. Here I went with 11. (replacing it with a distance is what you wish probably but I put here as an alternative)

enter image description here

with 1 cm mark distance

enter image description here

EDIT For the added style question, the code now gives

enter image description here

3
  • Thanks you very much, I'm using 'densely dashed' -- is there a way to set options like 'mark options={solid} or 'mark size=2.5pt'? Commented Mar 8, 2015 at 15:25
  • This is a really neat solution. However, if I use dashed as line type, I would also like to have the line in the legend dashed. This however is not the case for your latest example. Is there a possibility to preserve the original line style in the legend? Commented Jun 5, 2016 at 21:14
  • A simple \pgftransformresetnontranslations before \pgfuseplotmark{#1} improves this beautiful solution by keeping the orientation of the markers fixed, as in the legend. Commented Dec 30, 2016 at 11:24
6

Hee is a way that uses legend image post style and tikz decorations. We define a decoration first and then plot the same curve two times, once only with decorated marks, and then without markers.

\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} 

enter image description here

2
  • Thanks you very much, I'm using 'densely dotted' -- is there a way to set options like 'mark options={solid} or 'mark size=2.5pt' for the plot? Commented Mar 9, 2015 at 13:06
  • @harryhaller densely dotted for what, the line or the mark? Commented Mar 9, 2015 at 13:20
6

Done with MetaPost, with the actual sinus curve. (The legend box is still to be done.) For the markers, is it something like that you wish to obtain?

Note that it is only an adaptation of my answer to a very similar question here: Pgfplot, show mark when distance along the path is reached

Edit The cartouche is here now, with some other (minor) changes.

\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} 

enter image description here

5

If a manual solution is sufficient for your usage, you can use the mark repeat=<n> key to draw only every n th mark. Here, I've added 1 to each of your samples settings so that things work out in nice integers:

\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} 

enter image description here

3
  • Thanks you very much for your suggestion -- unfortunately the distance of all data points is not the same therefore it would be nice if I could define distance between the marks in cm. Commented Mar 8, 2015 at 8:24
  • @harryhaller Then what's wrong with the decoration stuff you posted in your question? Note that, pgfplots uses markers to mark the data points. TikZ markings decoration is different. Commented Mar 8, 2015 at 10:29
  • @percusse: it influences the legend, eg there are two markers in on the same legend entry and the marker is not centered, ie the marker position in the legend is a fuction of the distance. Furthermore, it's not really universal, ie I need to define a decoration for every maker type. I'm fine with the second point but it's awkward that the marker in the legend moves as a function of the distance. Commented Mar 8, 2015 at 11:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.