# Using path options to set color for a custom shading

I'm using a custom shading to make cylindrical bars.

The shading uses a color that is defined in the color list.

I can change the color by using a \colorlet expression. But I'd like to be able to do it with an option in the draw command.

Here's my code, with my latest attempts to set the color commented out. I haven't been able to find anything in the documentation or on stackexchange that shows me how to do it.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}

{\pgfpoint{0bp}{5bp}}
{color(0bp)=(white);
color(28bp)=(mycolor);
color(60bp)=(mycolor)}

{100bp}
{color(0bp)=(mycolor);
color(25bp)=(mycolor);
color(55bp)=(white);
color(75bp)=(mycolor);
color(100bp)=(mycolor)}

\def\cylindricalsphere{
\begin{pgfscope}
\pgfpathcircle{\pgfpoint{0}{0}}{5pt}
\end{pgfscope}}

\pgfdeclaredecoration{cylindricalbarspheres}{initial}
{
\state{initial}[width=1pt,next state=middle]{\cylindricalsphere}
\state{middle}[width=1pt]{}
\state{final}{\cylindricalsphere}}

\def\cylindricalsegment{
\begin{pgfscope}
\pgfpathrectanglecorners
{\pgfpoint{-.55pt}{-5pt}}
{\pgfpoint{.55pt}{5pt}}
\end{pgfscope}}

\pgfdeclaredecoration{cylindricalbarsegments}{initial}
{
\state{initial}[width=1pt,next state=middle]{
%\pgfkeysgetvalue{/tikz/path color}{pcolor}
%\colorlet{mycolor}{pcolor}
\cylindricalsegment}
\state{middle}[width=1pt]{
\cylindricalsegment}
\state{final}{}
}

\tikzset{
cylindricalbar/.style={
preaction={decorate,decoration=cylindricalbarspheres},
postaction={decorate,decoration=cylindricalbarsegments},
}}

\begin{document}
\begin{tikzpicture}

\colorlet{mycolor}{blue}
\path [cylindricalbar,color=green] (0,0) arc (90:0:3.5);
\end{tikzpicture}
\end{document}


You can declare a new TikZ option to store the color and use it into shading declarations.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}

\tikzset{
}

{\pgfpoint{0bp}{5bp}}
{color(0bp)=(white);
color(28bp)=(\mycolor);
color(60bp)=(\mycolor)}

{100bp}
{color(0bp)=(\mycolor);
color(25bp)=(\mycolor);
color(55bp)=(white);
color(75bp)=(\mycolor);
color(100bp)=(\mycolor)}

\def\cylindricalsphere{
\begin{pgfscope}
\pgfpathcircle{\pgfpoint{0}{0}}{5pt}
\end{pgfscope}}

\pgfdeclaredecoration{cylindricalbarspheres}{initial}
{
\state{initial}[width=1pt,next state=middle]{\cylindricalsphere}
\state{middle}[width=1pt]{}
\state{final}{\cylindricalsphere}}

\def\cylindricalsegment{
\begin{pgfscope}
\pgfpathrectanglecorners
{\pgfpoint{-.55pt}{-5pt}}
{\pgfpoint{.55pt}{5pt}}
\end{pgfscope}}

\pgfdeclaredecoration{cylindricalbarsegments}{initial}
{
\state{initial}[width=1pt,next state=middle]{
%\pgfkeysgetvalue{/tikz/path color}{pcolor}
%\colorlet{mycolor}{pcolor}
\cylindricalsegment}
\state{middle}[width=1pt]{
\cylindricalsegment}
\state{final}{}
}

\tikzset{
cylindricalbar/.style={
preaction={decorate,decoration=cylindricalbarspheres},
postaction={decorate,decoration=cylindricalbarsegments},
}}

\begin{document}
\begin{tikzpicture}
\path [cylindricalbar, cylindrical shading color=red] (0,0) arc (90:0:3.5);
\path [cylindricalbar, cylindrical shading color=green] (0,-0.5) arc (90:0:2.75);
\path [cylindricalbar, cylindrical shading color=blue] (0,-1) arc (90:0:2);
\path [cylindricalbar] (0,-1.5) arc (90:0:1.5);
\end{tikzpicture}
\end{document}


• I guess your bar endings disappeared in some cases, too? – cfr Mar 1 '17 at 2:07
• @cfr Do you have an example of disappearance? – Paul Gaborit Mar 1 '17 at 6:55
• @cfr. Yes. But I've not investigated the problem. – Ignasi Mar 1 '17 at 8:54
• @PaulGaborit: In my code, change green bar to be: \path [cylindricalbar, cylindrical shading color=green] (0,-0.5) arc (90:0:3.0); and lower end disappears. – Ignasi Mar 1 '17 at 8:55
• @PaulGaborit I tried the same with -0.5, but also had some where y was positive. I think if you change all the arcs to 90:0 in my answer, you'll get 2 disappearing lower ends, which is why I used 90:-5. – cfr Mar 1 '17 at 14:17

I tend to use a .code handler and just set the colour directly.

  cylindrical bar colour/.code={
\colorlet{mycolor}{#1}%
},
cylindrical bar colour=black,


This creates a key cylindrical bar colour whose argument will be used to set mycolor. black is used as an initial value.

Then,

\begin{tikzpicture}
\path [cylindricalbar] (0,.5)  arc (90:-5:4);
\path [cylindricalbar, cylindrical bar colour=green] (0,0) arc (90:-5:3.5);
\path [cylindricalbar, cylindrical bar colour=blue] (0,1) arc (90:-5:4.5);
\path [cylindricalbar, cylindrical bar colour=magenta] (0,1.5) arc (90:-5:5);
\end{tikzpicture}


gives

Complete code:

\documentclass[border=10pt,tikz]{standalone}
{\pgfpoint{0bp}{5bp}}
{color(0bp)=(white);
color(28bp)=(mycolor);
color(60bp)=(mycolor)}
{100bp}
{color(0bp)=(mycolor);
color(25bp)=(mycolor);
color(55bp)=(white);
color(75bp)=(mycolor);
color(100bp)=(mycolor)}
\def\cylindricalsphere{
\begin{pgfscope}
\pgfpathcircle{\pgfpoint{0}{0}}{5pt}
\end{pgfscope}}
\pgfdeclaredecoration{cylindricalbarspheres}{initial}
{
\state{initial}[width=1pt,next state=middle]{\cylindricalsphere}
\state{middle}[width=1pt]{}
\state{final}{\cylindricalsphere}}
\def\cylindricalsegment{
\begin{pgfscope}
\pgfpathrectanglecorners
{\pgfpoint{-.55pt}{-5pt}}
{\pgfpoint{.55pt}{5pt}}
\end{pgfscope}}
\pgfdeclaredecoration{cylindricalbarsegments}{initial}
{
\state{initial}[width=1pt,next state=middle]{
%\pgfkeysgetvalue{/tikz/path color}{pcolor}
%\colorlet{mycolor}{pcolor}
\cylindricalsegment}
\state{middle}[width=1pt]{
\cylindricalsegment}
\state{final}{}
}
\tikzset{
cylindricalbar/.style={
preaction={decorate,decoration=cylindricalbarspheres},
postaction={decorate,decoration=cylindricalbarsegments},
},
cylindrical bar colour/.code={
\colorlet{mycolor}{#1}%
},
cylindrical bar colour=black,
}
\begin{document}
\begin{tikzpicture}
\path [cylindricalbar] (0,.5)  arc (90:-5:4);
\path [cylindricalbar, cylindrical bar colour=green] (0,0) arc (90:-5:3.5);
\path [cylindricalbar, cylindrical bar colour=blue] (0,1) arc (90:-5:4.5);
\path [cylindricalbar, cylindrical bar colour=magenta] (0,1.5) arc (90:-5:5);
\end{tikzpicture}
\end{document}


By the way, are your cylinder endings meant to disappear in some cases? I had to do some experimentation to get 4 arcs which all had two round ends.