0

How do i make spaces between the groups, so that bars stop overlapping each other?.

Id thought it would automatically space them

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
    ybar,
    ymin=0,ymax=400,
    %enlargelimits=0.15,
                legend image code/.code={%
                    \draw[#1, draw=none] (0cm,-0.1cm) rectangle (0.6cm,0.1cm);
                },  
    ymajorgrids = true,
    legend style={at={(0.5,-0.10)},
      anchor=north,legend columns=-1},
    ylabel={Execution Time (ms)},
    symbolic x coords={R2G,Gaussian,Box,Sobel, Total Edge},
    xtick=data,
    nodes near coords,
    nodes near coords style={anchor=west,rotate=90,inner xsep=1pt},
    ]
\addplot coordinates {(R2G,33) (Gaussian,54)  (Box,127) (Sobel,246) (Total Edge, 145) };%CPU
\addplot [fill=teal!]  coordinates {(R2G,8.221) (Gaussian,13.3254)  (Box,14.958) (Sobel,29.935) (Total Edge, 43)  };%GPU
\addplot coordinates {(R2G,20.234959834) (Gaussian,26.492609995)  (Box,27.353843832) (Sobel,45.59262995) (Total Edge, 73.31923) };%FPGA
\addplot coordinates {(R2G,21.467651233) (Gaussian,38.359383243)  (Box,40.454379543) (Sobel,48.592629955) (Total Edge, 81.31923) };%HLS



\legend{CPU,GPU,FPGA,HLS}
\end{axis}
\end{tikzpicture}

\end{document}
5
  • 2
    You could add bar width=4pt, to the options of the plot.
    – user194703
    May 26, 2020 at 18:42
  • Seems like it just makes all the bars super thin.
    – Freon
    May 26, 2020 at 18:46
  • 1
    Well you could use bar width=6pt.
    – user194703
    May 26, 2020 at 18:47
  • i messed around the values, any number just makes it super thin, (just a line) . gyazo.com/afe8783785b93f2875a8e1a89d496b35
    – Freon
    May 26, 2020 at 18:48
  • 1
    For example add width=\textwidth,height=0.4\textwidth, to the axis options. I don't think there is an automatic solution, you need to adjust the width of the axis, the width of the bars and the space between the bars (e.g. ybar=0pt instead of just ybar removes the space between the bars within a group) to your liking. May 26, 2020 at 18:56

2 Answers 2

1

I'll be happy to remove this but with bar width=6pt I get

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\begin{document}
\begin{tikzpicture}
\begin{axis}[bar width=6pt,
    ybar,
    ymin=0,ymax=400,
    %enlargelimits=0.15,
                legend image code/.code={%
                    \draw[#1, draw=none] (0cm,-0.1cm) rectangle (0.6cm,0.1cm);
                },  
    ymajorgrids = true,
    legend style={at={(0.5,-0.20)},
      anchor=north,legend columns=-1},
    ylabel={Execution Time (ms)},
    symbolic x coords={R2G,Gaussian,Box,Sobel, Total Edge Detection},
    xtick=data,
    nodes near coords,
    nodes near coords style={anchor=west,rotate=90,inner xsep=1pt},
    x tick label style={text width=5em,anchor=north,align=center}
    ]
\addplot coordinates {(R2G,33) (Gaussian,54)  (Box,127) (Sobel,246) 
(Total Edge Detection, 145) };%CPU
\addplot [fill=teal!]  coordinates {(R2G,8.221) (Gaussian,13.3254)  
(Box,14.958) (Sobel,29.935) (Total Edge Detection, 43)  };%GPU
\addplot coordinates {(R2G,20.234959834) (Gaussian,26.492609995)  
(Box,27.353843832) (Sobel,45.59262995) (Total Edge Detection, 73.31923) };%FPGA
\addplot coordinates {(R2G,21.467651233) (Gaussian,38.359383243)  
(Box,40.454379543) (Sobel,48.592629955) 
(Total Edge Detection, 81.31923) };%HLS
\legend{CPU,GPU,FPGA,HLS}
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

So I am unable to reproduce the outcome of your comment.

ADDENDUM: If you want the tick texts to go over two lines, one option is to set the text width appropriately.

3
  • Thats really strange, maybe its because where i placed it, i put right under ymin=0
    – Freon
    May 26, 2020 at 18:58
  • Just a follow up from that, if i wanted to rename "total edge" -> "Total Edge detection", is there a way for the words to go onto the 2nd line? normally it would overlap the other labels ?
    – Freon
    May 26, 2020 at 19:08
  • 2
    @Freon You can set the text width of these ticks to some appropriate value.
    – user194703
    May 26, 2020 at 19:17
2

This is a "problem" quite often reported here on TeX.SX. For me the solution is to provide bar width and bar shift in axis units instead of as length. Then you just need to find a pair of these two keys that fit your aesthetics and can then change the axis width without changing the relatives between the bars width, separation in one group and separation between groups. But this can only be done when no symbolic coords are used.

And symbolic coords are (almost?) always used in conjunction with \addplot coordinates. For both I (personally) don't see any advantage compared to using a table (i.e. \addplot table) which offers much more flexibility.

So here is my proposed solution together with some other refinements of your code.

  1. Create a data table from the \addplot coordinates.
  2. Create xticklabels from the data table.
  3. State bar width and bar shift in (absolute) axis coordinates.
  4. Now you can freely scale the axis width.

Some related questions to yours and the answers are


Bonus stuff you could do

Having this solution so far you could even go one step further and add the \addplots in a loop instead of adding them one by one. For that see the answers to e.g.

And if you do that there remains one point that I haven't addressed so far: I removed the manual set color to the second \addplot command (because this is not relevant for answering your question). Of course when using the loop you can't state the color as an option to the \addplot command any more. But instead you can create your own cycle list and invoke it. For that see section 4.7.7 in the PGFPlots manual (v1.17) and of course you will find examples here on TeX.SX too.

Now you will perhaps think: "Why should I do all this stuff? This seems to be much more work/code than in my "simple" solution." And you are absolutely right with that. But the real benefit comes, when you create styles with all of this. Then you make sure all your plots look quite similar and also changes are done easily to all axis/plots by just changing the styles. Unfortunately I don't have good examples here, because questions here on TeX.SX are usually not about this topic. But I will state some very basic examples and maybe you can image how simple it is to change stuff then and maybe also, if you would combine the styles.

% used PGFPlots v1.17
\documentclass[border=5pt]{standalone}
\usepackage{pgfplotstable}
    % use this `compat' level or higher to be able to provide (relative) axis
    % units to `bar width' and `bar shift'
    \pgfplotsset{compat=1.7}
\begin{document}
\begin{tikzpicture}[
    % step 3a:
    % define the values for the width and shift of the bars
    % (the total "width" at one coordinate is 1. So the sum of the two
    %  values should be maximum 1 so the bars don't overlap.)
    % (The values could also be given directly to the keys, but this here is
    %  more general and allows arbitrary calculations of the values.
    %  So one could e.g. also first get the number of columns in the data
    %  table and compute `BarWidth` from that.)
    /pgf/declare function={
        BarWidth = 0.175;
        BarShift = BarWidth/2 + 0.05;
    },
]
        % step 1:
        % create a data table
        % (when there is a space in a string it needs to be surrounded by curly brackets
        %  or one could use another `col sep`)
        \pgfplotstableread{
            x                 CPU   GPU       FPGA           HLS
            R2G               33    8.221     20.234959834   21.467651233
            Gaussian          54    13.3254   26.492609995   38.359383243
            Box               127   14.958    27.353843832   40.454379543
            Sobel             246   29.935    45.59262995    48.592629955
            {Total \\ Edge}   145   43        73.31923       81.31923
        }\mydata

    \begin{axis}[
%        % step 4:
%        % adjust the `width` of the `axis` to your needs
%        width=\textwidth,
        % step 3b:
        % use the above defined values
        /pgf/bar width=BarWidth,
        /pgf/bar shift=BarShift,
        ybar,
        ymin=0,
        ymax=300,
        enlarge x limits={abs=0.5},
        ylabel={Execution Time (ms)},
        xtick=data,
        % step 2:
        % use `xticklabels from table` instead of stating `symbolic x coords`
        xticklabels from table={\mydata}{x},
        % (when you manually add line breaks you need to state how the text
        %  should be aligned)
        xticklabel style={
            align=center,
        },
        ymajorgrids=true,
        nodes near coords,
        nodes near coords style={
            anchor=west,
            rotate=90,
        },
        legend image code/.code={%
            \draw[#1, draw=none] (0cm,-0.1cm) rectangle (0.6cm,0.1cm);
        },
        legend style={
            % (use `xticklabel cs:` so you don't have to care about the `yshift`)
            at={(xticklabel cs:0.5)},
            anchor=north,
            legend columns=-1,
        },
        % use the `\coordindex` for all plots
        table/x expr={\coordindex},
    ]

        \addplot table [y=CPU]  {\mydata};
        \addplot table [y=GPU]  {\mydata};
        \addplot table [y=FPGA] {\mydata};
        \addplot table [y=HLS]  {\mydata};

        \legend{CPU,GPU,FPGA,HLS}
    \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.