1

I would like to make the color of a stacked bar chart (like here) depend on the data (like here) and here.

So far, here is what I have, but I don't know how to access the "color" column of the data to make the bar plot of a particular row that color.

\documentclass{article}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.14}
\usepackage[utf8]{inputenc}

% read in table \pgfplotstableread[col sep=comma]{ author,startyear,endyear,color abc,1530,1570,red def,1560,1570,green ghi,1560,1660,blue }\loadedtable

\begin{document}

\begin{tikzpicture} \begin{axis}[ nodes near coords xbar stacked configuration/.style={}, nodes near coords style={font=\footnotesize}, xbar stacked, xmin=1500, bar width=0.2cm, axis lines=left, width=\textwidth, height=7cm, enlarge y limits={abs=0.5}, ytick=\empty, ]

\addplot [draw=none, forget plot] table [col sep=comma,x=startyear, y expr=-\coordindex]{\loadedtable}; \addplot +[ nodes near coords, nodes near coords align={anchor=west}, point meta=explicit symbolic] table[col sep=comma,x expr=\thisrow{endyear}-\thisrow{startyear}, y expr=-\coordindex,meta=author]{\loadedtable}; \end{axis} \end{tikzpicture} \end{document}

rrrrr
  • 503

2 Answers2

2

Edit: Sorry for the previous answer. I was complete wrong about the stack bar plot function. I edit the answer to make it work.

This is not perfect solution, but it is working finally. Now the plot are drawn from single .txt file. The \addplot commands are only used to draw the axis and define the bar position (you can not have a legend for different bars). The bar is actually draw using \draw command after the \addplot. Using \foreach and datatool package commands to draw a thick line with different colors to represent the bar. You have any number rows in the .txt file, specify the color for each bar, define the vertical location using column y.

\begin{filecontents*}{a.txt}
author,startyear,endyear,y,color
abc1,1520,1570,6,red
def1,1540,1590,5,green
abc2,1550,1575,4,yellow
def2,1560,1570,3,green
ghi1,1560,1660,2,blue
ghi2,1620,1660,1,purple
jkl1,1590,1650,0,orange
\end{filecontents*}
\documentclass{article}
\usepackage{datatool}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\usepackage[utf8]{inputenc}
\DTLloaddb{tablea}{a.txt}
\foreach \i in {1,...,\DTLrowcount{tablea}}{
\edef\tempi{\noexpand\DTLassign{tablea}{\i}{\csname xst\i\endcsname=startyear,\csname xed\i\endcsname=endyear,\csname yp\i\endcsname=y,\csname col\i\endcsname=color}}\tempi}

\begin{document} \begin{tikzpicture} \begin{axis}[ nodes near coords xbar stacked configuration/.style={}, nodes near coords style={font=\footnotesize}, xmin=1500, bar width=0.2cm, xbar stacked, stack negative=on previous, axis lines=left, width=\textwidth, height=7cm, enlarge y limits={abs=0.5}, ytick=\empty, ] \addplot [draw=none, forget plot] table [col sep=comma,x=startyear, y=y]{a.txt}; \addplot[ nodes near coords,draw=none, nodes near coords align={anchor=west}, point meta=explicit symbolic] table [col sep=comma,x expr=\thisrow{endyear}-\thisrow{startyear}, y expr=\thisrow{y},meta index=0]{a.txt};

\foreach \i in {1,...,\DTLrowcount{tablea}}{ \edef\tempii{\noexpand\draw [line width=8pt,\csname col\i\endcsname] (axis cs:\csname xst\i\endcsname,\csname yp\i\endcsname) -- (axis cs:\csname xed\i\endcsname,\csname yp\i\endcsname);}\tempii}

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

enter image description here

Tom
  • 7,318
  • 4
  • 21
0

Here's how to add multiple of these plots in the same file (from @Tom):

\begin{filecontents*}{a.txt}
  author,startyear,endyear,y,color
  abc1,1520,1570,6,red
  def1,1540,1590,5,green
  abc2,1550,1575,4,yellow
  def2,1560,1570,3,green
  ghi1,1560,1660,2,blue
  ghi2,1620,1660,1,purple
  jkl1,1590,1650,0,orange
\end{filecontents*}
\begin{filecontents*}{b.txt}
  author,startyear,endyear,y,color
  jkl1,1590,1650,0,orange
\end{filecontents*}
\documentclass{article}
\usepackage{datatool}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\usepackage[utf8]{inputenc}
\DTLloaddb{tablea}{a.txt}
\foreach \i in {1,...,\DTLrowcount{tablea}}{
\edef\tempi{\noexpand\DTLassign{tablea}{\i}{\csname axst\i\endcsname=startyear,\csname axed\i\endcsname=endyear,\csname ayp\i\endcsname=y,\csname acol\i\endcsname=color}}\tempi}
\DTLloaddb{tableb}{b.txt}
\foreach \j in {1,...,\DTLrowcount{tableb}}{
\edef\tempj{\noexpand\DTLassign{tableb}{\j}{\csname bxst\j\endcsname=startyear,\csname bxed\j\endcsname=endyear,\csname byp\j\endcsname=y,\csname bcol\j\endcsname=color}}\tempj}

\begin{document} \begin{tikzpicture} \begin{axis}[ nodes near coords xbar stacked configuration/.style={}, nodes near coords style={font=\footnotesize}, xmin=1500, bar width=0.2cm, xbar stacked, stack negative=on previous, axis lines=left, width=\textwidth, height=7cm, enlarge y limits={abs=0.5}, ytick=\empty, ] \addplot [draw=none, forget plot] table [col sep=comma,x=startyear, y=y]{a.txt}; \addplot[ nodes near coords,draw=none, nodes near coords align={anchor=west}, point meta=explicit symbolic] table [col sep=comma,x expr=\thisrow{endyear}-\thisrow{startyear}, y expr=\thisrow{y},meta index=0]{a.txt};

\foreach \i in {1,...,\DTLrowcount{tablea}}{ \edef\tempii{\noexpand\draw [line width=8pt,\csname acol\i\endcsname] (axis cs:\csname axst\i\endcsname,\csname ayp\i\endcsname) -- (axis cs:\csname axed\i\endcsname,\csname ayp\i\endcsname);}\tempii}

\end{axis} \end{tikzpicture} \begin{tikzpicture} \begin{axis}[ nodes near coords xbar stacked configuration/.style={}, nodes near coords style={font=\footnotesize}, xmin=1500, bar width=0.2cm, xbar stacked, stack negative=on previous, axis lines=left, width=\textwidth, height=7cm, enlarge y limits={abs=0.5}, ytick=\empty, ] \addplot [draw=none, forget plot] table [col sep=comma,x=startyear, y=y]{b.txt}; \addplot[ nodes near coords,draw=none, nodes near coords align={anchor=west}, point meta=explicit symbolic] table [col sep=comma,x expr=\thisrow{endyear}-\thisrow{startyear}, y expr=\thisrow{y},meta index=0]{b.txt};

\foreach \j in {1,...,\DTLrowcount{tableb}}{ \edef\tempjj{\noexpand\draw [line width=8pt,\csname bcol\j\endcsname] (axis cs:\csname bxst\j\endcsname,\csname byp\j\endcsname) -- (axis cs:\csname bxed\j\endcsname,\csname byp\j\endcsname);}\tempjj}

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

rrrrr
  • 503
  • 1
    j was changing from 1 to maximum rows number in tableb as well, So the macro name was same for for tablea and tableb (e.g. \xst1, \xed1, \yp1, \col1 etc...) , So you need use different names for tableb e.g. \edef\tempj{\noexpand\DTLassign{tableb}{\j}{\csname bxst\j\endcsname=startyear,\csname bxed\j\endcsname=endyear,\csname byp\j\endcsname=y,\csname bcol\j\endcsname=color}}\tempj} – Tom Jun 09 '22 at 22:52
  • 1
    And foreach loop in second tikz need to be changed as well. \edef\tempjj{\noexpand\draw [line width=8pt,\csname bcol\j\endcsname] (axis cs:\csname bxst\j\endcsname,\csname byp\j\endcsname) -- (axis cs:\csname bxed\j\endcsname,\csname byp\j\endcsname);}\tempjj} – Tom Jun 09 '22 at 22:55
  • Thanks, that worked! I'll leave my edited reply above, unless you'd like to incorporate into your answer – rrrrr Jun 10 '22 at 03:47