5

I'd like to draw a closed plot path filled with pattern and surrounded by arrows:

enter image description here

When I used @Jake's solution to add arrows (Decorate a path with little arrows parallel to it) then the pattern made with the method proposed by @Domenico Camasta vanishes (Modified pattern does not see the pattern color option). The command postaction=decorate causes that the pattern filling the area is not created.

  1. What can I do to avoid executing 2-times the \addplot for the same path in the code below?
  2. Why removing of enlargelimits=true affects the distance between arrows and the plot path?
  3. How to trim both axes at the origin of the coordinate system?

The code is following:

\documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\usepackage{tikz}
\pgfplotsset{compat=newest}

\usetikzlibrary{decorations.markings}
\usetikzlibrary{patterns}
\usepgfplotslibrary{fillbetween}

\definecolor{mygreen}{rgb}{0.00000,0.60000,0.00000}

\makeatletter
\pgfdeclarepatternformonly[\LineSpace]{my north east lines}%
    {\pgfqpoint{-1pt}{-1pt}}%
    {\pgfqpoint{\LineSpace}{\LineSpace}}%
    {\pgfqpoint{\LineSpace}{\LineSpace}}%
    {\pgfsetcolor{\tikz@pattern@color}
     \pgfsetlinewidth{0.4pt}
     \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}
     \pgfpathlineto{\pgfqpoint{\LineSpace + 0.1pt}{\LineSpace + 0.1pt}}
     \pgfusepath{stroke}
    }
\makeatother

\newdimen\LineSpace
\tikzset{
    line space/.code={\LineSpace=#1},
    line space=9pt
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[%
width=10cm,
height=7cm,
axis on top=true,
axis x line=middle,
axis y line=middle,
xtick=\empty,
ytick=\empty,
extra x ticks={0,0.1},
extra x tick labels={$x_{min}$,$x_{max}$},
extra y ticks={600},
extra y tick labels={$F_{max}$},
extra y tick style={yticklabel style={xshift=0.8ex, anchor=west}},
xlabel={piston position},
ylabel={force},
enlargelimits=true
]
\addplot[
    name path=A,color=blue,solid,forget plot,smooth,
    decoration={
        markings,
        mark=between positions 0.1 and 1 step 3em with {\draw [-latex] (-2mm,0) -- (2mm,0);},
        raise=0.6cm
    },
    postaction=decorate
]
table[row sep=crcr]{%
    0       60\\
    0.005   450\\
    0.025   550\\
    0.1     600\\
} node [above=0.8ex,pos=0.96] {$F_{\rightarrow}(x)$};
\addplot[
    name path=B,color=mygreen,solid,forget plot,smooth,
    decoration={
        markings,
        mark=between positions 0.1 and 1 step 3em with {\draw [-latex] (-2mm,0) -- (2mm,0);},
        raise=0.6cm
    },
    postaction=decorate
]
table[row sep=crcr]{%
    0.1     600\\
    0.095   200\\
    0.065   100\\
    0       60\\
} node [below=1.0ex,pos=0.93] {$F_{\leftarrow}(x)$};
\addplot fill between[of=A and B,
                      split,
                      every segment no 1/.style={pattern=my north east lines,pattern color=gray}
                     ];
\node[fill=white] at (0.05,350) {\textcolor{gray}{dissipated energy}};
\end{axis}
\end{tikzpicture}
\end{document}
5

This kind of approximate graph is a nice one to do in Metapost because you have flexibility to draw as you like, without fighting the constraints of a tool designed for plotting functions. I've used the subpath feature to decorate the path with arrows.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

minf = 13;
maxf = 144; 
minx = 0;
maxx = 233;

path f, xx, yy; 
z0 = (minx,minf);
z1 = (1/30[minx,maxx],14/15[minf,maxf]);
z2 = (maxx,maxf);
z3 = z1 rotatedabout(1/2[z0,z2],180);
f = z0 .. controls z1 .. z2 .. controls z3 .. cycle;

xx = (minx-2,0) -- (maxx+20,0);
yy = (0,-2) -- (0,maxf+20);

for i = -maxx step maxx/34 until maxx:
  draw (left--right) scaled maxx rotated 45 shifted(i,0) withcolor .8 white;
endfor
clip currentpicture to f;

drawoptions(withcolor .5 white);
drawarrow xx; 
drawarrow yy;
draw (up  --down ) scaled 2 shifted (maxx,0);
draw (left--right) scaled 2 shifted (minx,maxf);
drawoptions();

draw subpath(0,1) of f withcolor .67 blue;
draw subpath(1,2) of f withcolor .56 green;

label.bot(btex $x_{\min}$ etex, (minx,0));
label.bot(btex $x_{\max}$ etex, (maxx,0));
label.lft(btex $F_{\max}$ etex, (minx,maxf));

label(btex piston position etex, ((minx+maxx)/2,-20));
label(btex force etex rotated 90, (-20,(minf+maxf)/2));

label(btex $F_{\to}(x)$        etex, point 0.9 of f shifted 12 up)   withcolor .67 blue;
label(btex $F_{\leftarrow}(x)$ etex, point 1.7 of f shifted 14 down) withcolor .56 green;

picture de; de = thelabel(btex dissipated energy etex, center f);
unfill bbox de; draw de withcolor .5 white;

% the arrow decorations
ahangle := 30; ahlength := 3; r=12; 
for a = 2r step 2.55r until arclength f - r:
  drawarrow subpath(arctime a of f, arctime a+r of f) of f 
            shifted 3 unitvector(direction arctime a of f of f rotated 90);
endfor

endfig;
end.
  • f you don't mind using more macros than those contained in the plain format, shorter alternatives are provided by the hatching package for the hatchings, and the enlarged operator of the metafun format for the path underneath the arrow decorations (g = f enlarged 3bp; ... drawarrow subpath(arctime a of g, arctime a+r of g) of g;...) – Franck Pastor Mar 20 '15 at 20:12
  • Thx for the code. In fact I'm doing my first steps in the use of PGF/TikZ. So in my case it is a problem if I have to learn also Metapost. – forrest Mar 21 '15 at 5:25
  • @forrest, ah but it's so much nicer! :-) – Thruston Mar 21 '15 at 8:49

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.