2

Here is an example of a shape that is formed with 4 lines and 2 curves. I then use the same data to fill that shape with a color. The (correct) result looks like this:

enter image description here

The MWE code is here:

\begin{tikzpicture}
% define and draw the shape
\draw [thin] (0.5,4) -- (1.5,5) -- (2.5,4);
\draw plot[smooth,tension=0.5] coordinates{(2.5,4) (2,3.2) (2.1,2.5) (1.7,1.7) (2,1)};
\draw [thin] (2,1) -- (1,0) -- (0,1);
\draw plot[smooth,tension=0.5] coordinates{(0,1) (0.4,1.7) (0.5,2.5) (0.8,3.2) (0.5,4)};
% fill the shape
\fill [blue,opacity=0.2] (0.5,4) -- (1.5,5) -- (2.5,4)
-- plot[smooth,tension=0.5] coordinates{(2.5,4) (2,3.2) (2.1,2.5) (1.7,1.7) (2,1)} 
-- (2,1) -- (1,0) -- (0,1)
-- plot[smooth,tension=0.5] coordinates{(0,1) (0.4,1.7) (0.5,2.5) (0.8,3.2) (0.5,4)};
\end{tikzpicture}

My problem is that I am unable to save and reuse the curves (that are long in reality). For example, this does not work:

\begin{tikzpicture}
% define and draw the shape
\path[save path=\mypath1] plot[smooth,tension=0.5] coordinates{(2.5,4) (2,3.2) (2.1,2.5) (1.7,1.7) (2,1)};
\draw [thin] (0.5,4) -- (1.5,5) -- (2.5,4);
\draw [use path=\mypath1];
\draw [thin] (2,1) -- (1,0) -- (0,1);
\draw plot[smooth,tension=0.5] coordinates{(0,1) (0.4,1.7) (0.5,2.5) (0.8,3.2) (0.5,4)};
% fill the shape
\fill [blue,opacity=0.2] (0.5,4) -- (1.5,5) -- (2.5,4)
-- plot[smooth,tension=0.5] coordinates{(2.5,4) (2,3.2) (2.1,2.5) (1.7,1.7) (2,1)} 
-- (2,1) -- (1,0) -- (0,1)
-- plot[smooth,tension=0.5] coordinates{(0,1) (0.4,1.7) (0.5,2.5) (0.8,3.2) (0.5,4)};
\end{tikzpicture}

Furthermore I would not know how to include the saved path coordinates within the single \fill command. Is there a simple solution to this?

The actual Use Case

It helps to illustrate my requirement with a brief description of my use case. I generate a fair amount of LaTeX code - currently over 1000 lines but one line can contain 13500 bytes of coordinate data. A PDF is the final product. Some graphs contain lines that delineate specific areas that can be shaded for clarity. Shapes that are a combination of partial border lines (straight lines) and actual graph lines (Bézier curves) require coloring.

Although I entered relevant but misleading data into my MWE, consider the central dark blue band from top-right to bottom-left to be a representative shape. (The diagram below is taken from another program that possibly existed before TikZ was born.)

enter image description here

Note that a diagonal graph line also borders neighboring areas that require different coloring. My objective is to economize on repetitive coordinate data, the majority of which describes the curves, to keep the overall .tex file size to a minimum, also being economical with run-time memory requirements, e.g. in MiKTeX. Execution speed is not a priority. So the idea to use macros, kindly suggested by Jasper Habicht, is actually very appropriate. Multiple named paths that can be saved and (re-)used is apparently not available within TikZ (yet :-). The spath3 library is another interesting option that requires a steeper learning curve and possibly goes beyond my original aims. Thanks to all contributors!

5
  • 1
    Does it work when using \mypath instead of \mypath1? The fact that \mypath1 is not a valid control sequence name could be an issue. Apr 27, 2023 at 20:33
  • Good point. YES, it works. But a) how do I identify the second curve with a distinct name and b) how can I include them both within the single \fill command?
    – Aendie
    Apr 27, 2023 at 20:45
  • 1
    The spath3 library can do quite extensive things with paths, including saving and re-using but also melding paths together and transforming them after saving. Apr 27, 2023 at 21:19
  • I'm honored by your comment - spath3 is a great achievement but I don't understand how it could solve my problem. I prefer to use as few libraries as possible ... maybe the tikz team have a solution?
    – Aendie
    Apr 27, 2023 at 21:36
  • @Aendie given how large the TikZ codebase is, loading one more library is not going to have a huge effect. Apr 28, 2023 at 16:14

1 Answer 1

2

You can always store parts of a path in a macro and use it to stick together larger parts. So, for example, this works:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\newcommand{\mypathA}{
    (1.5,5) -- (2.5,4) -- (2,1) -- (1,0)
}

\fill[blue!20, draw=black] 
    (0.5,4) -- \mypathA -- (0,1) -- cycle;

\end{tikzpicture}
\end{document}

However, if there you want to use the plot function in such a construct, you would need to make sure that the plotted parts are expanded beforehand. So, you can do:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\newcommand{\mypathA}{
    plot[smooth, tension=0.5] coordinates {(2.5,4) (2,3.2) (2.1,2.5) (1.7,1.7) (2,1)}
}
\newcommand{\mypathB}{
    plot[smooth, tension=0.5] coordinates {(0,1) (0.4,1.7) (0.5,2.5) (0.8,3.2) (0.5,4)}
}

\edef\temp{\noexpand\fill[blue!20, draw=black] 
    (0.5,4) -- (1.5,5) -- (2.5,4) -- \mypathA -- 
    (2,1) -- (1,0) -- (0,1) -- \mypathB -- cycle;}\temp

\end{tikzpicture}
\end{document}

enter image description here

If your question, however, is how to fill and draw a shape in one move, than you can simply do:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\fill[blue!20, draw=black] 
    (0.5,4) -- (1.5,5) -- (2.5,4) -- 
    plot[smooth, tension=0.5] coordinates {(2.5,4) (2,3.2) (2.1,2.5) (1.7,1.7) (2,1)} 
    -- (2,1) -- (1,0) -- (0,1) -- 
    plot[smooth, tension=0.5] coordinates {(0,1) (0.4,1.7) (0.5,2.5) (0.8,3.2) (0.5,4)} 
    -- cycle;

\end{tikzpicture}
\end{document}

The output looks exactly like above.

1
  • Clearly a good answer - and one that I overlooked completely. The fill operation is separate from draw in my case as the straight lines form the border of the graph area, which in fact is orthogonal (vertical and horizontal). Per graph I would only need a few macros that I can redefine (saving memory space).
    – Aendie
    Apr 28, 2023 at 14:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .