2

I appreciate the fact that LaTeX is WYSIWYW but overtime I am questioning myself wether the idea of WYSIWYW for pure graphics is still reasonable. Today it took me more than one hour to realize the following picture with the following code (and two others which are very similar to this).

On my Lenovo ThinkPad L530 (Ubuntu and Openbox) it takes more than 15 seconds to compile each time and reducing the samples from 2000 to 500 it still takes more than 3 seconds with a much worse result. I am still not satisfied of this image beacuse of the sharpness of the intersections of the parabola with the horizontal and vertical lines. So here are my questions:

  1. What was the right code I should have used to make a fast compiling and good looking picture?
  2. How long does it normally take you to come out with the right code for such an image?
  3. Which WYSIWYG alternatives to tikz you would recommend for this kind of pictures?

Thank you for your patience.

enter image description here

\documentclass{standalone}
\usepackage{tikz,pgfplots}

\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}

\begin{document} 
\begin{tikzpicture}
\begin{axis}[
axis lines=middle,
axis line style=->,
xmin=-.4,xmax=1.4,
ymin=-.4,ymax=2.4,
x=3cm,
y=3cm,
xlabel=$p$,
ylabel=$s$,
]

\addplot[name path=A,black,restrict x to domain=-0.001:0.359, samples= 2000] {2};
\addplot[name path=B,black,restrict x to domain=-0.001:0.359, samples= 2000] {1+0.5*x};
\addplot[gray!40] fill between[of=A and B];
\addplot[name path=C,black,restrict x to domain=0.349:1.001, samples= 2000] {2};
\addplot[name path=D,black,restrict x to domain=0.349:1.001, samples= 2000] {2*sqrt(x)};
\addplot[gray!40] fill between[of=C and D];

\addplot[restrict x to domain=-0.001:1.001, samples= 2000, smooth,line width=0.35mm, -]{2*sqrt(x)};
\addplot[restrict y to domain=-0.001:2.001, samples= 2000, smooth,line width=0.35mm, -]({0},{x});
\addplot[restrict x to domain=-0.001:1.001, samples= 2000, smooth,line width=0.35mm, -]{2};
\addplot[restrict x to domain=-0.301:1.301, samples= 2000, smooth,line width=0.15mm, -]{1+0.5*x};

\end{axis}
\end{tikzpicture}
\end{document}
  • my very old pc (8+ years, first generation of pentium, but 8GB ram and ssd) need less the 1 second to compile your mwe. :-) – Zarko Oct 6 '17 at 10:20
  • sorry, my pc need 15 second ... however, your code can be simplified. see answer below. – Zarko Oct 6 '17 at 10:37
  • 1
    You could externalize the tikzpicture. That way it is only recreated if you change something. (see tex.stackexchange.com/a/1475/36296) – user36296 Oct 6 '17 at 10:45
5
\documentclass[border=3mm]{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
axis lines=middle,
axis line style=->,
xmin=-.4,xmax=1.4,
ymin=-.4,ymax=2.4,
x=3cm,
y=3cm,
xlabel=$p$,
ylabel=$s$,
samples=100% <--- moved here
]

\addplot[name path=A,domain=0:0.36] {2};
\addplot[name path=B,domain=0:0.36] {1+0.5*x};
\addplot[gray!40] fill between[of=A and B];
%
\addplot[name path=C,domain=0.35:1] {2};
\addplot[name path=D,domain=0.35:1] {2*sqrt(x)};
\addplot[gray!40] fill between[of=C and D];

\addplot[domain=0:1, line width=0.35mm]{2*sqrt(x)};
\addplot[domain=0:2, line width=0.35mm]({0},{x});
\addplot[domain=0:1, line width=0.35mm]{2};
\addplot[domain=-0.3:1.3, line width=0.15mm]{1+0.5*x};
\end{axis}
\end{tikzpicture}
\end{document}

i made the following changes:

  • reduce number of samples to 100 and move declaration to axis options (for reason of shorter code)
  • remove smooth options
  • replaced restrict x to domain withdomain
  • rounded limits of domain (from -0.001 to 0, etc)

after this changes the computation time on my old pc was reduced about 4 seconds and resulted images (to my taste) looks better :-)

addendum: as pointed Sergei Golovan in his comment below, for drawing function square root function on domain 0:1 is sensible to draw it as inverse function in the parametric form.

Since the square root function have infinite derivative around zero, it's hard to draw it nice, i.e. you need many sample points. Derivative of the inverse function in origin is zero, therefore it can be drawn with few samples. for example, with only 25 samples result with use of inverse function is visible almost the same as with use of direct function at 200 samples.

\documentclass[border=3mm]{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
axis lines=middle,
axis line style=->,
xmin=-.4,xmax=1.4,
ymin=-.4,ymax=2.4,
x=3cm,
y=3cm,
xlabel=$p$,
ylabel=$s$,
samples=20
]

\addplot[name path=A,domain=0:0.36] {2};
\addplot[name path=B,domain=0:0.36] {1+0.5*x};
\addplot[gray!40] fill between[of=A and B];
%
\addplot[name path=C,domain=0.35:1] {2};
\addplot[name path=D,domain=0.35:1] {2*sqrt(x)};
\addplot[gray!40] fill between[of=C and D];

% parametric form of inverse function
\addplot[domain=0:2, line width=0.35mm] ({x*x/4},  % <-- x values
                                         {x}       % <-- y values
                                         );
\addplot[domain=0:1, line width=0.35mm]{2};
\addplot[domain=-0.3:1.3, line width=0.15mm]{1+0.5*x};
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

  • I'd also replace \addplot[domain=0:1, line width=0.35mm]{2*sqrt(x)}; by the parametrized \addplot[domain=0:2, line width=0.35mm]({x*x/4},{x}); to avoid a kink near zero. – Sergei Golovan Oct 6 '17 at 10:43
  • @SergeiGolovan, please be so kind and give me a tip, where (if it is) described parametric way of function's calculation ? – Zarko Oct 6 '17 at 11:21
  • I can find many examples of parametric plots in the pgfplots documentation (pgfplots.sourceforge.net/pgfplots.pdf). Though if you ask how the new parametrization was chosen, I just used an inverse function. Since the square root function have infinite derivative around zero, it's hard to make its plot nice (you need many sample points). The inverse function doesn't have this problem. – Sergei Golovan Oct 6 '17 at 14:37
4

For fun, a pstricks version:

\documentclass[x11names, svgnames, border=3pt]{standalone}
\usepackage{pstricks-add}
\usepackage{auto-pst-pdf} %% for pdflatex compilation

\begin{document}

\psset{unit=2cm, algebraic, plotstyle=curve, plotpoints=500,arrowinset=0.125, arrowsize=3pt, linejoin=1,labelsep = 8pt}

\begin{pspicture*}(-0.4,-0.3)(1.6,2.5)
    \psaxes[linecolor=LightSteelBlue3, ticksize =-3pt 3pt, tickcolor=LightSteelBlue3, arrows=->, subticksize =1, subtickcolor=LightSteelBlue3, subtickwidth=0.4pt, subticks=2, Dx=1, Dy=1](0,0)(-0.4,- 0.3)(1.5, 2.5) [$p$,120] [$s$,-30]
    \uput[d](0.5,0){0.5} \uput[l](0,0.5){0.5}\uput[l](0,1.5){1.5}
    \psplot{0}{1}{2*sqrt(x)}
    \psplot[linewidth=0.5pt]{-0.4}{1.5}{1 + x/2}
    \pscustom[linecolor=SteelBlue, fillstyle=solid, fillcolor=Gainsboro!80!Lavender]{\psline(0,1)(0,2)(1,2)\psplot{1}{0.343}{2*sqrt(x)}\closepath}
\end{pspicture*}

\end{document} 

enter image description here

  • 1
    +1 for enthusiasm for pstricks. ones i try to learn it, but i give up and now stick only with tikz :-) – Zarko Oct 6 '17 at 16:41
  • I think pstricks is much easier to learn than tikz (latex syntax!), and often less verbose. But tikz has nevertheless very interesting features. – Bernard Oct 6 '17 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.