Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorations on the patch

Tags:

tikz

pgf

pgfplots

I'm stuck at finding the solution to "embed" arrowhead on the patch plot which would indicate loop flow direction. The decorations with post action will not work (for apparent reason).

Is there any trick how to accomplish it?

I tried:

  • adding the arrows manually onto the background layer (as I couldn't find the way to draw only the arrow head the finished positioning was clunky at best and the result was mediocre)
  • spath and remembering the path (but the path is empty, duh)

Current code to draw the hysteresis loop:

\documentclass[tikz,margin=10pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usepackage{helvet}
\usepackage{amsmath}
\usepackage[czech]{babel}
\usepackage{pgfplots, pgfplotstable}

\pgfplotsset{compat=1.18}
\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{fillbetween}

\usetikzlibrary{babel, calc}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{decorations.pathreplacing}
\usetikzlibrary{arrows.meta, spath3}

\renewcommand{\familydefault}{\sfdefault}

\iflanguage{czech}{}

\begin{document}

\begin{tikzpicture} [
    guide/.style={thin, dashed, themeGrey},
    flow arrow/.style={-{Latex[scale=0.75]}, thick, themeBlue!60, shorten >=1pt, } %shorten <=3pt
]

\definecolor{themeBlue}{RGB}{1, 103, 143}
\definecolor{themeOrange}{RGB}{221, 109, 16}
\definecolor{themeTeal}{RGB}{18, 54, 69}
\definecolor{themeGrey}{RGB}{120, 121, 124}

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground} 

\begin{axis}[
    width=10cm, height=10cm, samples = 100,
    ymin=-5, ymax=5,
    xmin=-5, xmax=5,
    enlargelimits=false, clip=false, 
    axis on top, axis lines*=middle, axis line style = {semithick, -latex},
    yticklabel style={text width=1.75em, align=left},
%
    xlabel={$\text{H}$},
    xtick={1.5, 4}, 
    xticklabels={$\text{+H}_{\text{c}}$, $\text{+H}_{\text{m}}$},
    extra x ticks={-4, -1.5},
    extra x tick labels={$\text{-H}_{\text{m}}$, $\text{-H}_{\text{c}}$},
    extra x tick style={
        xticklabel style={yshift=0.5ex, anchor=south}
    },
%
    ylabel={$\text{B}$},
    ytick={2.5, 4}, 
    yticklabels={$\text{+B}_{\text{r}}$, $\text{+B}_{\text{m}}$},
    extra y ticks={-4, -2.5},
    extra y tick labels={$\text{-B}_{\text{m}}$, $\text{-B}_{\text{r}}$},
    extra y tick style={
        yticklabel style={xshift=5ex, text width=1.5em, align=left}
    },
%
    every axis plot/.style={thick},
    axis x line=middle,    % put the x axis in the middle
    axis y line=middle,
    every axis x label/.style={at={(ticklabel* cs:1.01)}, anchor=west},
    every axis y label/.style={at={(ticklabel* cs:1.01)}, anchor=south,},
]

\addplot [mesh, patch type=quadratic spline, themeBlue, dashed] coordinates {
   (0,0) (4,4) (1.5,1)% first segment
};

\addplot [patch, patch type=quadratic spline, themeBlue] coordinates {
   (-4,-4) (-1.5,0) (-2.5,-2.8) % first segment
   (-1.5,0) (4,4) (0,2.5) % second segment
};

\addplot [mark=*, only marks, ultra thin, themeBlue] plot coordinates {
    (4, 4) (-4, -4)
    (1.5, 0) (-1.5, 0)
    (0, -2.5) (0, 2.5)
};

\addplot [patch, patch type=quadratic spline, themeBlue] coordinates {
     (-4,-4) (1.5,0) (0,-2.5) % left, right, middle-> first segment
     (1.5,0) (4,4) (2.5,2.8) % left, right, middle-> second segment
};

% Adding arrows to indicate flow direction
\begin{pgfonlayer}{background}
\end{pgfonlayer}

\addplot [guide] plot coordinates { (0, 4) (4, 4) (4, 0) };

\end{axis}
\end{tikzpicture}
\end{document}

Current graph

like image 488
jr.root.cs Avatar asked Jan 30 '26 04:01

jr.root.cs


1 Answers

This is a rather old post, but the answer can still be useful for others. Actually, I cannot answer directly to the question, and I am not sure it is even possible. The decoration requires a path, while patch plots do not handle single paths.

I can however offer an alternative that uses (cubic) Bézier splines instead of quadratic splines. A cubic Bézier path is determined by 4 points (2 endpoints and 2 controls points) and specified as (corner 1) .. controls (control point A) and (control point B) .. (corner 2) (see p. 472 in the manual).

Such a path can be decorated and made visually close to your original drawing. The drawback is that you have to specify and tune more points to have a nice curve.

\documentclass[tikz,margin=10pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usepackage{helvet}
\usepackage{amsmath}
\usepackage[czech]{babel}
\usepackage{pgfplots, pgfplotstable}

\pgfplotsset{compat=1.18}
\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{fillbetween}

\usetikzlibrary{babel, calc}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{decorations.pathreplacing}
\usetikzlibrary{arrows.meta, spath3}

\renewcommand{\familydefault}{\sfdefault}

\iflanguage{czech}{}

% Define the paths
\newcommand{\pathup}{%
(axis cs:4,4)
.. controls (axis cs:2,3.6) and (axis cs:0.5,2.9) ..
(axis cs:0,2.5)
.. controls (axis cs:-0.5,2.1) and (axis cs:-1.3,1.2) ..
(axis cs:-1.5,0)
.. controls (axis cs:-1.7,-1.2) and (axis cs:-2.,-3.2) ..
(axis cs:-4,-4)
}

\newcommand{\pathdown}{%
(axis cs:-4,-4)
.. controls (axis cs:-2,-3.6) and (axis cs:-0.5,-2.9) ..
(axis cs:0,-2.5)
.. controls (axis cs:0.5,-2.1) and (axis cs:1.3,-1.2) ..
(axis cs:1.5,0)
.. controls (axis cs:1.7,1.2) and (axis cs:2.,3.2) ..
(axis cs:4,4)
}


\begin{document}

\begin{tikzpicture} [
    guide/.style={thin, dashed, themeGrey},
    flow arrow/.style={-{Latex[scale=0.75]}, thick, themeBlue!60, shorten >=1pt, } %shorten <=3pt
]

\definecolor{themeBlue}{RGB}{1, 103, 143}
\definecolor{themeOrange}{RGB}{221, 109, 16}
\definecolor{themeTeal}{RGB}{18, 54, 69}
\definecolor{themeGrey}{RGB}{120, 121, 124}

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground} 

\begin{axis}[
    width=10cm, height=10cm, samples = 100,
    ymin=-5, ymax=5,
    xmin=-5, xmax=5,
    enlargelimits=false, clip=false, 
    axis on top, axis lines*=middle, axis line style = {semithick, -latex},
    yticklabel style={text width=1.75em, align=left},
%
    xlabel={$\text{H}$},
    xtick={1.5, 4}, 
    xticklabels={$\text{+H}_{\text{c}}$, $\text{+H}_{\text{m}}$},
    extra x ticks={-4, -1.5},
    extra x tick labels={$\text{-H}_{\text{m}}$, $\text{-H}_{\text{c}}$},
    extra x tick style={
        xticklabel style={yshift=0.5ex, anchor=south}
    },
%
    ylabel={$\text{B}$},
    ytick={2.5, 4}, 
    yticklabels={$\text{+B}_{\text{r}}$, $\text{+B}_{\text{m}}$},
    extra y ticks={-4, -2.5},
    extra y tick labels={$\text{-B}_{\text{m}}$, $\text{-B}_{\text{r}}$},
    extra y tick style={
        yticklabel style={xshift=5ex, text width=1.5em, align=left}
    },
%
    every axis plot/.style={thick},
    axis x line=middle,    % put the x axis in the middle
    axis y line=middle,
    every axis x label/.style={at={(ticklabel* cs:1.01)}, anchor=west},
    every axis y label/.style={at={(ticklabel* cs:1.01)}, anchor=south,},
]

% Draw the points
\addplot [mark=*, only marks, ultra thin, themeBlue] plot coordinates {
    (4, 4) (-4, -4)
    (1.5, 0) (-1.5, 0)
    (0, -2.5) (0, 2.5)
};

% Draw the curves
\draw[themeBlue, thick] \pathup;
\draw[themeBlue, thick] \pathdown;

% Draw arrows along the same curves
\draw[decorate, decoration={markings, mark=between positions 0.1 and 0.9 step 20mm with {\arrow{>}}}] \pathup;
\draw[decorate, decoration={markings, mark=between positions 0.1 and 0.9 step 20mm with {\arrow{>}}}] \pathdown;

\addplot [guide] plot coordinates { (0, 4) (4, 4) (4, 0) };

\end{axis}
\end{tikzpicture}
\end{document}


Hysteresis plot with arrows

like image 93
Thomas Bernat Avatar answered Feb 02 '26 01:02

Thomas Bernat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!