2

I am learning to do the following type of stacked bar chart (originally produced with Tableau): enter image description here I don't really care that the text "Target Class" is on the upper left, in fact I like it better on the left y axis. I also don't care that the larger bars appear above or below. What I really care is simplicity of code. What I have been doing seems really complicated and long, and I am wondering if there is a simpler way of doing it.

Here is what I have so far, which is based mainly on this post (see link on comments):

\documentclass{article}                                                     
\usepackage{tikz}                                                           
\usepackage{pgfplots}                                                       

\begin{document}                                                            
\begin{tikzpicture}                                                         
\begin{axis}[                                                               
  xbar stacked,                                                             
  bar width=15pt,                                                           
  xlabel={Count of Errors and Predicted Class},                             
  ylabel={Target Class},
  yticklabels={E,T,M,N,A,6/W,O,K,R,S,7,F,I,1,3,G,X,4,5,B,H},                
  symbolic y coords={E,T,M,N,A,6/W,O,K,R,S,7,F,I,1,3,G,X,4,5,B,H},          
  xtick={0,2,4,6,8,10,12,14,16,18},                                         
  ytick=data,                                                               
  width=12.2cm,                                                             
  height=7.1cm,                                                             
  axis y line*=none,                                                        
  axis x line*=bottom,                                                      
  ]                        
\addplot[fill=gray!50!black,draw=black] coordinates {(5,E) (8,T) (8,M) (5,N) (3,A) (6,6/W) (5,O)};
\addplot[fill=gray!50!black,draw=black] coordinates {(4,E) (6,T) (3,M) (2,N) (3,A) (1,6/W) (1,O)};
\addplot[fill=gray!50!black,draw=black] coordinates {(3,E) (1,T) (2,M) (2,N) (2,A) (0,6/W) (1,O)};
\addplot[fill=gray!50!black,draw=black] coordinates {(2,E) (1,T) (1,M) (1,N) (1,A) (0,6/W) (0,O)};
\addplot[fill=gray!50!black,draw=black] coordinates {(1,E) (0,T) (0,M) (1,N) (1,A) (0,6/W) (0,O)};
\addplot[fill=gray!50!black,draw=black] coordinates {(1,E) (0,T) (0,M) (0,N) (0,A) (0,6/W) (0,O)};
\addplot[fill=gray!50!black,draw=black] coordinates {(1,E) (0,T) (0,M) (0,N) (0,A) (0,6/W) (0,O)};

\coordinate (ES) at (-10,0);                                                
\coordinate (EM) at (16mm,0);                                               
\coordinate (ET) at (41mm,0);                                               
\coordinate (EH) at (60mm,0);                                               
\coordinate (EA) at (72.8mm,0);                                             
\coordinate (EO) at (79mm,0);                                               
\coordinate (EP) at (85.3mm,0);                                             

\coordinate (TA) at (-10,7.5mm);                                            
\coordinate (TS) at (34.7mm,7.5mm);                                         
\coordinate (TE) at (72.8mm,7.5mm);                                         
\coordinate (TN) at (79mm,7.5mm);                                           

\coordinate (MN) at (-10,15.5mm);                                           
\coordinate (MT) at (34.7mm,15.5mm);                                        
\coordinate (MA) at (54mm,15.5mm);                                          
\coordinate (MS) at (66.6mm,15.5mm);                                        

\coordinate (NM) at (-10,23.1mm);                                           
\coordinate (NA) at (16mm,23.1mm);                                          
\coordinate (NH) at (28.5mm,23.1mm);                                        
\coordinate (NT) at (41mm,23.1mm);                                          
\coordinate (NY) at (47.4mm,23.1mm);                                        

\coordinate (AE) at (-10,30.8mm);                                           
\coordinate (AN) at (3.2mm,30.8mm);                                         
\coordinate (AM) at (22.1mm,30.8mm);                                        
\coordinate (AP) at (34.7mm,30.8mm);                                        
\coordinate (AT) at (41mm,30.8mm);                                          

\coordinate (6W7) at (-10,38.2mm);                                          
\coordinate (6W3) at (22.1mm,38.2mm);                                       

\coordinate (OE) at (-10,46mm);                                             
\coordinate (O3) at (16mm,46mm);                                            
\coordinate (OC) at (22.1mm,46mm);                                          

\end{axis}                                                                  
\node[style={text=white}] at (ES) {S};                                      
\node[style={text=white}] at (EM) {M};                                      
\node[style={text=white}] at (ET) {T};                                      
\node[style={text=white}] at (EH) {H};                                      
\node[style={text=white}] at (EA) {A};                                      
\node[style={text=white}] at (EO) {O};                                      
\node[style={text=white}] at (EP) {P};                                      

\node[style={text=white}] at (TA) {A};                                      
\node[style={text=white}] at (TS) {S};                                      
\node[style={text=white}] at (TE) {E};                                      
\node[style={text=white}] at (TN) {N};                                      

\node[style={text=white}] at (MN) {N};                                      
\node[style={text=white}] at (MT) {T};                                      
\node[style={text=white}] at (MA) {A};                                      
\node[style={text=white}] at (MS) {S};                                      

\node[style={text=white}] at (NM) {M};                                      
\node[style={text=white}] at (NA) {A};                                      
\node[style={text=white}] at (NH) {H};                                      
\node[style={text=white}] at (NT) {T};                                      
\node[style={text=white}] at (NY) {Y};                                      

\node[style={text=white}] at (AE) {E};                                      
\node[style={text=white}] at (AN) {N};                                      
\node[style={text=white}] at (AM) {M};                                      
\node[style={text=white}] at (AP) {P};                                      
\node[style={text=white}] at (AT) {T};                                      

\node[style={text=white}] at (6W7) {7};                                     
\node[style={text=white}] at (6W3) {3};                                     

\node[style={text=white}] at (OE) {E};                                      
\node[style={text=white}] at (O3) {3};                                      
\node[style={text=white}] at (OC) {C};                                      
\end{tikzpicture}                                                           
\end{document}                            

The output: enter image description here

So, to re-state the question. Is there a simpler way of achieving a similar output? Is there another way of doing the same but in fewer lines of code?

  • This is the link: pgfplots.net/tikz/examples/stacked-bar-plot I could not post it because of low reputation. – Pablo Rivas Feb 20 '17 at 15:24
  • Welcome to TeX.SX. Sure, I suggest you put all data to an external file providing x values, y values (as index numbers, i.e. 0,1,...,y), the corresponding y tick label (i.e., E, T, M, ...), the x values as Deltas and the corresponding labels inside the bars. If you could do that and add it as edit to your question, we will have it much easier to help you. Here is an example where a data file/inline table -- instead of coordinates -- is used to provide the data for a stacked bar chart: tex.stackexchange.com/questions/86369/… – Stefan Pinnow Feb 20 '17 at 15:48
  • Can you please have a look at the answers in tex.stackexchange.com/questions/36114/… and let us know if it answers your question ? – percusse Feb 20 '17 at 18:12
  • @StefanPinnow, thanks that helps. I accepted your answer. Thanks, that is much simpler. – Pablo Rivas Feb 24 '17 at 22:39
1

This should be what you are searching for. Please note that this is just a redefined version of your MWE and does not represent the Tableau output (because the data are there in another order (and more)).

For more details on how it works, please have a look at the comments in the code

% used PGFPlots v1.14
    % put the data into a file
    % (for that I "transposed" it compared to the given `coordinates' in your
    %  MWE and added columns for the labeling of the bars)
    \begin{filecontents*}{bardata.dat}
        y   x1 x2 x3 x4 x5 x6 x7  z1 z2 z3 z4 z5 z6 z7
        E   5  4  3  2  1  1  1   S  M  T  H  A  O  P
        T   8  6  1  1  0  0  0   A  S  E  N  {} {} {}
        M   8  3  2  1  0  0  0   N  T  A  S  {} {} {}
        N   5  2  2  1  1  0  0   M  A  H  T  Y  {} {}
        A   3  3  2  1  1  0  0   E  N  M  P  T  {} {}
        6/W 6  1  0  0  0  0  0   7  3  {} {} {} {} {}
        O   5  1  1  0  0  0  0   E  3  C  {} {} {} {}
    \end{filecontents*}
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    \pgfplotsset{
        % use this `compat' level or higher to use the advanced positioning
        % features of `nodes near coords' in stacked bar plots
        compat=1.9,
    }
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        width=12.2cm,
        height=7.1cm,
        axis y line*=none,
        axis x line*=bottom,
        xbar stacked,
        bar width=15pt,
        xmin=0,
        % for simplicity use `ytick=data'
        ytick=data,
        % use a column of the data table for the ytick labels
        yticklabels from table={bardata.dat}{y},
        xlabel={Count of Errors and Predicted Class},
        ylabel={Target Class},
        % we want to show `nodes near coords' ...
        nodes near coords,
        % ... with white text color ...
        nodes near coords style={
            text=white,
        },
        % ... and symbolic values
        point meta=explicit symbolic,
    ]
        % cycle through the columns of the data file
        % (indices are starting from 0)
        \foreach \i in {1,...,7} {
                % store the column number containing the `meta' data
                \pgfmathtruncatemacro{\MetaColNo}{7+\i}
            % draw the plot ...
            \addplot [
                draw=white,
                fill=black,
            ] table [
                % ... using the column index `\i' as x value, ...
                x index=\i,
                % ... the `\coordindex' as y value, and ...
                y expr=\coordindex,
                % ... the (stored) column number `\MetaColNo' as meta value
                meta index=\MetaColNo,
            ] {bardata.dat};
        }
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

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.