# Multiple Color PGF Shape

I have a Two shapes I use as a nodes. Currently I have Two styles, which overlap, which limits the number of nodes I can have by half. What I am trying to do is create a pgf shape so that both shapes are together in one node. The problem is using the specific colors for the specific lines.

The following is an example what I am currently using.

\tikzset{
iso/.style={kite, draw=green, kite vertex angles=120,  minimum size=1cm, outer sep=0pt}, % this creates the kite
isobox/.style={draw,opacity=0,path picture={
\draw[draw opacity =1,color=blue] (path picture bounding box.north east) -- (path picture bounding box.south east);
\draw[draw opacity =1,color=blue] (path picture bounding box.north west) -- (path picture bounding box.south west);
\draw[draw opacity =1,color=blue] (path picture bounding box.north) -- (path picture bounding box.south);
\draw[draw opacity =1,color=red] (path picture bounding box.north west) -- (path picture bounding box.north east);
\draw[draw opacity =1,color=red] (path picture bounding box.south west) -- (path picture bounding box.south east);
\draw[draw opacity =1,color=yellow] (path picture bounding box.west) -- (path picture bounding box.east);
},  minimum size=1cm, outer sep=0pt,inner sep=0pt}
}
\begin{document}
\begin{tikzpicture}
\node[iso] (IGA0) {};
\node[isobox,draw,fit=(IGA0)](BXA0) {};
\end{tikzpicture}
\end{document}


I also have the following code, which is derived from pgf shape example

...
\pgfdeclareshape{IGBox}{
...
\backgroundpath{
% Rectangle box
\pgfpathrectanglecorners{\southwest}{\northeast}
\pgf@anchor@IGBox@center
\pgf@xa=\pgf@x \pgf@ya=\pgf@y
\pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgf@xc=\pgf@x \pgf@yc=\pgf@y
\pgf@xd=\pgf@x \pgf@yd=\pgf@y
\pgfmathsetlength\pgf@x{\pgfshapeminwidth} % size depends on font size
\pgfmathsetlength\pgf@y{\pgfshapeminheight}

\advance\pgf@ya by 0.5\pgf@y
\advance\pgf@xb by 0.5\pgf@x
\advance\pgf@yc by -0.5\pgf@y
\advance\pgf@xd by -0.5\pgf@x

\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yd}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfclosepath
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfclosepath
\pgfpathmoveto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yd}}

\pgfclosepath
}
}
...
\tikzset{add font/.code={\expandafter\def\expandafter\tikz@textfont\expandafter{\tikz@textfont#1}}}

% Define default style for this node
\tikzset{IGBox/port labels/.style={font=\sffamily\scriptsize}}

\tikzset{every IGBox node/.style={draw,minimum width=2cm,minimum
height=1cm,very thick,outer sep=0pt,inner sep=0pt,cap=round,add
font=\sffamily}}
...


This code results in the correct shape, and anchoring, but not the correct line colors.

Below are three figures, which show what I want, and how it is currently made.

Figure 1 is the kite, created using Tikzset.

Figure 2 is the box, created using Tikzset.

Figure 3 is the shape, created using \pgfdeclareshape{IGBox}

Figure 4 is what I want.

I want do be able to create Figure 1 as a single node using \pgfdefineshape

There is a reason I need this, but that reason isn't really relevant to my question.

I can figure out the anchoring,and the \pgrpathmoveto and \pgfpathlineto but what I cannot figure out is how to create Figure 1 with the colors shown above.

I would prefer to be using the second code block as the base for my shape, as I do need to be able to use anchoring.

• This is now new question ... – Zarko Oct 17 '19 at 17:05

## 3 Answers

You were almost there. All you need to do is to use the append after command key (and the knowledge that the previous node gets stored in \tikzlastnode) to combine the two styles.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{shapes.geometric,fit}
\tikzset{
iso/.style={kite, draw=green, kite vertex angles=120,  minimum size=1cm, outer sep=0pt}, % this creates the kite
isobox/.style={draw,opacity=0,path picture={
\draw[draw opacity =1,color=blue] (path picture bounding box.north east) -- (path picture bounding box.south east);
\draw[draw opacity =1,color=blue] (path picture bounding box.north west) -- (path picture bounding box.south west);
\draw[draw opacity =1,color=blue] (path picture bounding box.north) -- (path picture bounding box.south);
\draw[draw opacity =1,color=red] (path picture bounding box.north west) -- (path picture bounding box.north east);
\draw[draw opacity =1,color=red] (path picture bounding box.south west) -- (path picture bounding box.south east);
\draw[draw opacity =1,color=yellow] (path picture bounding box.west) -- (path picture bounding box.east);
},  minimum size=1cm, outer sep=0pt,inner sep=0pt},
combined/.style={iso,append after
command={node[fit=(\tikzlastnode),isobox]{}}}
}
\begin{document}
\begin{tikzpicture}
\draw node[combined] (IGA0) {};
\end{tikzpicture}
\end{document}


• perfect, thank you, I was thinking of using pgf, but if i don't have to, even better. – cdickstein Oct 16 '19 at 19:20
• @cdickstein If you need all the anchors, the cleaner option is to indeed define a new shape. Or you could use a pic and define the anchors as coordinates. Both answers have at this point the problem that you cannot transform them (try e.g. rotate). The problem with a shape will be that it will be rather cumbersome to make it fully general, i.e. to allow users to change the colors of the lines, but it is doable. On the other hand, if you need only the graph and the anchors, a pic may be the easier way to go. Please let me know if you want me to spell this out. – Schrödinger's cat Oct 17 '19 at 4:27
• I do not need the colors to change, they are set in stone, but I do need the corners of the rectangle and of the kite/diamond to be anchored. – cdickstein Oct 17 '19 at 12:04
\documentclass[tikz, margin=3mm]{standalone}

\newcommand\ppbb{path picture bounding box}
\tikzset{
isobox/.style = {minimum width=3cm, minimum height=2cm, inner sep=0pt,
path picture={%
\draw[blue] (\ppbb.north east) -- (\ppbb.south east)
(\ppbb.north west) -- (\ppbb.south west)
(\ppbb.north) -- (\ppbb.south);
\draw[red]  (\ppbb.north west) -- (\ppbb.north east)
(\ppbb.south west) -- (\ppbb.south east);
\draw[yellow]   (\ppbb.west) -- (\ppbb.east);
\draw[green]    (\ppbb.west) -- (\ppbb.north) --
(\ppbb.east) -- (\ppbb.south) -- cycle;
}   }
}
\begin{document}
\begin{tikzpicture}
\node[isobox] (BXA0) {};
\end{tikzpicture}
\end{document}


gives

• This answer Might Be Better, But I do Need Anchoring – cdickstein Oct 16 '19 at 19:21
• @cdickstein, what anchoring? isobox have all anchors or rectangle. – Zarko Oct 16 '19 at 19:41
• the vertexes of the kite, and of the rectangle – cdickstein Oct 17 '19 at 12:03
• In desired shape you cannot have kite and rectangle anchors in the same time. This is only possible, if you combine those shapes as you did in your question. – Zarko Oct 17 '19 at 12:27
• it would be more accurate to state that the location should be at those points, not necessarily dependent on the shapes themselves. i would also like to use anchor names, left,right,up,down etc... the reason is for ease of typing, and much easier for self orientation. – cdickstein Oct 17 '19 at 16:03

I found the answer through shear luck and experimenting with code order. Using \pgfusepath{} and \pgfsetstrokecolor{}, the following is the answer to the "PGF Shape" question I asked.

  \backgroundpath{
% Rectangle box
\pgfpathrectanglecorners{\southwest}{\northeast}
% Angle (>) for clock input
\label{IGBox Inner Lines}
\pgf@anchor@IGBox@center
%    \pgf@xba=\pgf@x \pgf@yba=\pgf@y
%    \pgf@xbb=\pgf@x \pgf@ybb=\pgf@y
%    \pgf@xbc=\pgf@x \pgf@ybc=\pgf@y
%    \pgf@xbd=\pgf@x \pgf@ybd=\pgf@y

\pgf@xa=\pgf@x \pgf@ya=\pgf@y
\pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgf@xc=\pgf@x \pgf@yc=\pgf@y
\pgf@xd=\pgf@x \pgf@yd=\pgf@y

\pgfmathsetlength\pgf@x{\pgfshapeminwidth} % size depends on font size
\pgfmathsetlength\pgf@y{\pgfshapeminheight}

\advance\pgf@ya by 0.5\pgf@y
\advance\pgf@xb by 0.5\pgf@x
\advance\pgf@yc by -0.5\pgf@y
\advance\pgf@xd by -0.5\pgf@x

\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yd}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfsetstrokecolor{green}
\pgfclosepath
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfsetstrokecolor{blue}
\pgfclosepath
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yd}}
\pgfsetstrokecolor{yellow}
\pgfclosepath


It still has some minor tweaks, but the general answer is here.

I found the general answer from here