add tag
topnush
I would like to draw these two pictures of 4 bar charts.

![060-Problem-Set-1-pdf.png](/image?hash=e0e0f345c560c2eb8210c0ffdf29f11eec1916a959054d8e50524bbfd5e696b9)

and


![060-Problem-Set-1-pdf (1).png](/image?hash=3c9beae35fe1e63f2137f17e595f894fd51d6960322a52016eb2871afcc30a97)


The numbers in the rectangles are their areas but I am happy to enter those values manually. 

I thought tikz might be the right route but I am stuck at the very beginning using this skeleton code which is meant to represent the first of the four bar charts.

```
\documentclass[tikz]{standalone}
\usepackage{pgfplots}

\begin{document}
%---------------------------------------------------------------%
\begin{tikzpicture}
\begin{axis}[
    area style,
    xticklabels={4, 2, 3, 1},
    yticklabels = {}
    ]
\addplot[ybar interval,mark=no] plot coordinates { (0, 4) (5, 2) (10, 3) (15, 1)};

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

To make my question more limited and specific,  how I make the bars narrower and put the numbers below the bars as in the images I have posted?
Top Answer
Skillmon
# Just using idiomatic Ti*k*Z

The following uses just a few lines of idiomatic Ti*k*Z to draw your first chart with the rectangle, you should be able to extent this for the others as well.


```
\documentclass[tikz,border=3.14]{standalone}

\newcommand\barwd{5mm}

\begin{document}
\begin{tikzpicture}
  % bars
  \foreach[count=\n]\x in {4,2,3,1}
    \draw[fill=gray]
      (\n*\barwd,0) coordinate(bar\n-ll)
        rectangle
      +(\barwd,\x*\barwd) coordinate(bar\n-tr)
      +(.5*\barwd,0) node[below]{\x}
      ;
\end{tikzpicture}
\begin{tikzpicture}
  % bars
  \foreach[count=\n]\x in {4,2,3,1}
    \draw[fill=gray]
      (\n*\barwd,0) coordinate(bar\n-ll)
        rectangle
      +(\barwd,\x*\barwd) coordinate(bar\n-tr)
      +(.5*\barwd,0) node[below]{\x}
      ;
  % black rectangle
  \filldraw
    (bar1-ll) % first bar of rectangle (1-indexed)
      rectangle node[color=white,font=\bfseries]{6}
    (bar2-tr % smallest bar of rectangle
      -|
    bar3-tr) % last bar of rectangle
    ;
\end{tikzpicture}
\end{document}
```

Results:

![topnush-barcharts-1.png](/image?hash=17e5de0f4e0ae04b3196ce7ba4628cdcb4a261c18a10666eea8830d287c60b02)

![topnush-barcharts-2.png](/image?hash=d54d79fcfab7d081970aab298dd51b5ea3884ec81be3ca03fc979b70d20c0a26)
Answer #2
Skillmon
# Using an expandable macro in a path

The following defines a macro `\bars` that should be used as part of a Ti*k*Z path. It'll draw your bar charts using `node`s. The bars are numbered from left to right, starting at index 0. Each bar consists of two nodes, one being the bar and named `bar<n>` (`<n>` being the index), and the other being the number beneath it named `number<n>`.

The macro takes the following arguments:

- an optional argument in `[]` containing key=value input
- an optional argument in `()`, if this is given each node name will be prefixed with `#2-` (so the contents of that argument followed by a hyphen)
- a mandatory argument containing the list of values of your bars

Your values can be floating point numbers, but values smaller than zero aren't supported.

`\bars` is fully expandable and will expand to a bunch of idiomatic Ti*k*Z instructions to draw the charts.

Each chart element has an associated Ti*k*Z style you might change to contain default values (only change stuff below the comments `%% user specified styling`).

The chart will start with the south west corner of the zeroth bar at the current point of the path. Afterwards the current path will be located at the south east corner of the last bar (moved to the left by one `line width`).

## Key=Val interface

The following keys are supported in `#1`:

- `unit` the width of the bars and the height of the value 1 (initially 5mm)
- `line width` the width of the lines surrounding the bars, the lines will not add to the `unit`-width, meaning that thick line widths will lead to thinner overall charts, as neighbouring bars share their vertical lines.
- `number options` additional Ti*k*Z options to use for the height numbers below the bars
- `rectangle options` additional Ti*k*Z options to use for the rectangles drawn over the bar chart
- `rectangle number` additional Ti*k*Z options to use for the rectangle number nodes
- `rectangles` this one is special and described below.

Every unknown key is used as additional Ti*k*Z options to use for the bar nodes.

### The `rectangles` key

The `rectangles` key accepts an optional argument (will be used as additional Ti*k*Z options for the rectangles additionally to the `rectangle options`). It should also get a comma separated list of number ranges that specify which bars should be covered by rectangles in the form `<a>-<b>` with `<a>` the first and `<b>` the last bar to cover (indexed starting with 0).

## MWE:

```
\documentclass[tikz,border=3.14]{standalone}

\usepackage{expkv-cs}

\makeatletter
\ekvcHashAndForward\bars@kv\bars@do
  {
     unit = 5mm
    ,line width = \pgflinewidth
    ,number options = {}
    ,rectangles = {}
    ,rectangle options = {}
    ,rectangle number  = {}
    ,...
  }
\newcommand\bars@do[3]
  {%
    \expanded{\unexpanded{\bars@firstbar{#1}{#2}}\ekvcsvloop\bars@bar{#3}}%
    \bars@done
    \ekvcValueSplitFast{rectangle options}{#1}%
      {\ekvcValueSplitFast{rectangles}{#1}\bars@rectangles}{#2}{#3}{#1}%
  }
\newcommand\bars@firstbar[3]{#30{#1}{#2}}
\newcommand\bars@done[3]{}
\newcommand\bars@bar[5]
  {%
    \if1\fpeval{(#4)<0}\ekverr{bars}{Values smaller than 0 not supported}\fi
    node
      [
        /bars/bar={\ekvcValue{line width}{#2}}{\ekvcValue{unit}{#2}}{#4}%
        \ekvcValue{...}{#2}%
      ]
      (#3bar#1)
      {}
    node [/bars/number,\ekvcValue{number options}{#2}]
      (#3number#1) at (#3bar#1.south) {#4}
    (#3bar#1.south east) ++({-(\ekvcValue{line width}{#2})},0)
    \expandafter#5\expandafter{\the\numexpr#1+1\relax}{#2}{#3}%
  }
\newcommand\bars@rectangles[1]
  {%
    \ekvoptargTF
      \bars@rectangles@opts
      {\bars@rectangles@noopts{#1}}%
      #1\mark\stop
  }
\long\def\bars@rectangles@opts#1#2\mark\stop#3#4#5#6%
  {\expanded{\ekvcsvloop{\bars@rectangle{#3,#1}{#4}{#5}{#6}}{#2}}}
\long\def\bars@rectangles@noopts#1#2\stop#3#4#5#6%
  {\expanded{\ekvcsvloop{\bars@rectangle{#3}{#4}{#5}{#6}}{#1}}}
\newcommand\bars@rectangle[5]{\bars@rectangle@split#5\stop{#1}{#2}{#3}{#4}}
\long\def\bars@rectangle@split#1-#2\stop#3#4#5#6%
  {%
    % Args: >>=
    %   #1: first bar of rectangle
    %   #2: last bar of rectangle
    %   #3: options for rectangles
    %   #4: naming prefix
    %   #5: list of bars
    %   #6: list of options
    % =<<
    \expanded
      {%
        \unexpanded{\bars@rectangle@firstheight{#1}{#2}}%
        \ekvcsvloop\bars@rectangle@height{#5}%
      }%
    \bars@rectangle@done
    \bars@rectangle@stop{#3}{#4}{#6}%
  }
\newcommand\bars@rectangle@firstheight[3]{#30{Inf}0{#1}{#2}}
\newcommand\bars@rectangle@height[7]% >>=
  {%
    % Args: >>=
    %   #1: current bar
    %   #2: minimum height
    %   #3: bar of minimum height
    %   #4: first bar of rectangle
    %   #5: last bar of rectangle
    %   #6: current bar's height
    %   #7: next iteration
    % =<<
    \ifnum#1>#5
      \bars@rectangle@do{#2}{#3}{#4}{#5}%
    \fi
    \expandafter#7\expanded
      {%
        {\the\numexpr#1+1\relax}%
        \ifnum#4>#1
          {#2}%
          {#3}%
        \else
          \if1\fpeval{(#6)<(#2)}%
            {#6}%
            {#1}%
          \else
            {#2}%
            {#3}%
          \fi
        \fi
      }%
      {#4}{#5}%
  }% =<<
\newcommand\bars@rectangle@done[5]
  {%
    % Args: >>=
    %   #1: current bar
    %   #2: minimum height
    %   #3: bar of minimum height
    %   #4: first bar of rectangle
    %   #5: last bar of rectangle
    % =<<
    \ifnum#1>#5
      \bars@rectangle@do{#2}{#3}{#4}{#5}%
    \fi
    \ekverr{bars}{Rectangle out of bounds}%
    \bars@rectangle@cleanup
  }
\long\def\bars@rectangle@cleanup#1\bars@rectangle@stop#2#3#4{}
\long\def\bars@rectangle@do#1#2#3#4\fi#5\bars@rectangle@stop#6#7#8%
  {%
    % Args: >>=
    %   #1: minimum height
    %   #2: bar of minimum height
    %   #3: first bar of rectangle
    %   #4: last bar of rectangle
    %   #5: garbage
    %   #6: options for rectangles
    %   #7: naming prefix
    %   #8: list of options
    % =<<
    \fi
    node
      [
        /bars/rectangle=%
          {\the\numexpr#4-#3+1\relax}%
          {#1}%
          {\ekvcValue{unit}{#8}}%
          {\ekvcValue{line width}{#8}}%
        ,#6%
      ]
      (lastrectangle)
      at (#7bar#3.south west)
      {}
    node
      [/bars/rectangle number,\ekvcValue{rectangle number}{#8}]
      at (lastrectangle)
      {\fpeval{(#4-#3+1)*(#1)}}
  }
\newcommand\bars{\unexpanded\expanded{{\iffalse}}\fi\bars@args}
\NewExpandableDocumentCommand \bars@args { O{} d() m }
  {%
    \IfNoValueTF{#2}%
      {\bars@kv{#1}{}}%
      {\bars@kv{#1}{#2-}}%
        {#3}%
    \iffalse{{\fi}}%
  }
\makeatother

% default options for bars' underlying TikZ nodes go here
\pgfqkeys{/bars}
  {%
     bar/.style n args ={3}%
      {%
        % #1: line width
        % #2: unit
        % #3: bar height
        %% positioning relevant options
         anchor=south west
        ,inner sep={-.5*(#1)}
        ,outer sep={.5*(#1)}
        ,line width={#1}
        ,text width={#2}
        ,text height={#3*(#2)}
        ,text depth=0pt
        ,minimum size=0pt
        %% user specified styling
        ,draw
      }%
    ,number/.style=%
      {%
        %% positioning relevant options
        anchor=north
        %% user specified styling
      }
    ,rectangle/.style n args ={4}%
      {%
        % #1: number of bars
        % #2: height
        % #3: unit
        %% positioning relevant options
         anchor=south west
        ,inner sep={-.5*(#4)}
        ,outer sep={.5*(#4)}
        ,line width={#4}
        ,text width={#1*(#3)-(#1-1)*(#4)}
        ,text height={(#2)*(#3)}
        ,text depth=0pt
        ,minimum size=0pt
        %% user specified styling
        ,draw
        ,fill
      }%
    ,rectangle number/.style =%
      {%
        %% positioning relevant options
        %% user specified styling
         color=white
        ,font=\bfseries
      }
  }

\begin{document}
\begin{tikzpicture}
  \path
    (0,0)
    \bars[line width=3pt](first){4,2.5,3,1}
    (first-bar3.south east) ++(1,0)
    \bars[fill=gray]{2,7,1,8,3,0,5,4}
    (0,-5)
    \bars[fill=gray,rectangles=0-2]{4,2.5,3,1}
    (bar3.south east) ++(1,0)
    \bars[fill=gray,rounded corners,rectangles=[{purple,rounded corners}]{6-7,0-2}]{2,7,1,8,3,0,5,4}
    ;
\end{tikzpicture}
\end{document}
```

Output:

![topnush-barcharts-1.png](/image?hash=7f09ce3eac5d1e1f72b061039b2118bd8762fdc4b0d45858a24d799238420f2c)

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.