8

I want to combine the two figures below into one. That is having an arrow with colors going from red at the bottom to blue at the top. Could anyone show me how to do it?

enter image description here

  • 1
    Could you please check whether Tikz: Shading a path without any filling helps you? – Claudio Fiandrino Aug 25 '14 at 9:32
  • Thanks, could we assign colors to specific points on the path? I see only top and bottom color there. – wererabit Aug 25 '14 at 9:53
  • I think you can easily do it by changing type of shading; if you look on the pgfmanual there is also a rainbow shading. – Claudio Fiandrino Aug 25 '14 at 10:01
  • Please post a Minimum Working Example which produces the output you've posted (since you've already got that far). – cfr Aug 25 '14 at 12:15
8

The problem with trying to do a "color-bar" style shading is that in the process of fitting a shading to a path PGF scales a shading so that only the center quarter of the shading is seen (see "Using Shadings" in the manual).

This means that either a color-bar has to be "squidged" into the center quarter of a shading definition, which is a pain to to manually, or the path to be shaded has to be clipped, and scaled manually which can also be a bit of a nuisance.

The following shows one way of specifying a color-bar with a list of named colors (assumed to occupy equal width of the bar) and automatically generate a (more-or-less) appropriate shading:

\documentclass[tikz, border=5]{standalone}
\usetikzlibrary{shapes.arrows}
\makeatletter
\def\createshadingfromlist#1#2#3{%
  \pgfutil@tempcnta=0\relax
  \pgfutil@for\pgf@tmp:={#3}\do{\advance\pgfutil@tempcnta by1}%
  \ifnum\pgfutil@tempcnta=1\relax%
    \edef\pgf@spec{color(0)=(#3);color(100)=(#3)}%
  \else%
    \pgfmathparse{50/(\pgfutil@tempcnta-1)}\let\pgf@step=\pgfmathresult%
    %
    \pgfutil@tempcntb=1\relax%
    \pgfutil@for\pgf@tmp:={#3}\do{%
      \ifnum\pgfutil@tempcntb=1\relax%
        \edef\pgf@spec{color(0)=(\pgf@tmp);color(25)=(\pgf@tmp)}%
      \else%
        \ifnum\pgfutil@tempcntb<\pgfutil@tempcnta\relax%
          \pgfmathparse{25+\pgf@step/4+(\pgfutil@tempcntb-1)*\pgf@step}%
          \edef\pgf@spec{\pgf@spec;color(\pgfmathresult)=(\pgf@tmp)}%
        \else%
          \edef\pgf@spec{\pgf@spec;color(75)=(\pgf@tmp);color(100)=(\pgf@tmp)}%
        \fi%
      \fi%
      \advance\pgfutil@tempcntb by1\relax%
    }%
  \fi%
  \csname pgfdeclare#2shading\endcsname{#1}{100}\pgf@spec%
}

\createshadingfromlist{shading1}{vertical}{red,yellow,green,cyan,blue}
\createshadingfromlist{shading2}{vertical}{red,yellow}
\createshadingfromlist{shading3}{vertical}{black,blue,cyan,white}

\begin{document}
\begin{tikzpicture}[colorbar arrow/.style={
  shape=double arrow,
  double arrow head extend=0.125cm, 
  shape border rotate=90, 
  minimum height=5cm,
  shading=#1 
}]
\node [colorbar arrow=shading1] at (0,0) {};
\node [colorbar arrow=shading2] at (1,0) {};
\node [colorbar arrow=shading3] at (2,0) {};
\end{tikzpicture}  
\end{document}

enter image description here

4

An example with PSTricks. Run it with xelatex

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pstricks-add,pst-slpe}
\begin{document}
\begin{pspicture}(9,10)
\psset{doublesep=1cm}
\psBigArrow[fillstyle=slope,slopebegin=cyan!100!white!80,slopeend=black,slopeangle=0](1,0)(1,10)
\psBigArrow[fillstyle=slope,slopebegin=red,slopeend=blue,slopeangle=0](4,0)(4,10)
\psBigArrow[fillstyle=slope,slopebegin=red,slopeend=green,slopeangle=0](7,0)(7,10)
\end{pspicture}
\end{document}

enter image description here

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.