1

When I use xbar and data to display a progress bar for some kind of data I could not find any information how it is possible to equal the space between each data line over more than one chart.

My question is: Is there a possibility to have the same width for each tick for multiple tables? As in my example the chart with four entries should have less than half the height of the chart with ten entries.

\documentclass{standalone}
\usepackage{tikz,pgfplots}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four}
  ]
  \addplot [fill=gray] coordinates {
    (1,One)
    (3,Two)
    (0,Three)
    (5,Four)
  };
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
  \begin{axis}[
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten}
  ]
  \addplot [fill=gray] coordinates {
    (4,One)
    (2,Two)
    (1,Three)
    (1,Four)
    (0,Five)
    (5,Six)
    (4,Seven)
    (2,Eight)
    (2,Nine)
    (0,Ten)
  };
  \end{axis}
\end{tikzpicture}
\end{document}

I tried working with width and height in the axis options, but that didn't work for charts with three or less entries, because the bars seemed to be above or below the chart.

Edit for clarification:

What i want to display is something like that: Latex Output

Some new tries, neither worked:

I tried the answer of Schrördinger's Cat and added an example of adjusted width and height. But neither delivered a suitable result:

\documentclass{standalone}
\usepackage{tikz,pgfplots}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten},
    yticklabels={One, Two}
  ]
  \addplot [fill=gray] coordinates {
    (4,One)
    (2,Two)
    (0,Ten)
  };
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
  \begin{axis}[
    xbar,
    ytick = data,
    xmin = 0, xmax = 1,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two},
    yticklabels={One, Two}
  ]
  \addplot [fill=gray] coordinates {
    (1,One)
    (1,Two)
  };
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
  \begin{axis}[
    xbar,
    width = 8.5cm,
    height = 3cm,
    ytick = data,
    xmin = 0, xmax = 1,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two},
    yticklabels={One, Two}
  ]
  \addplot [fill=gray] coordinates {
    (1,One)
    (1,Two)
  };
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

2
  • 1
    Hi and welcome. I don't quite understand your problem. Can you add a freehand drawing or an explanatory image?
    – AndréC
    Feb 17, 2020 at 17:09
  • @AndréC Thank you for your help. I've added an example to the main post. Feb 18, 2020 at 8:29

3 Answers 3

0

I'm not sure whether or not there is an option to do this automatically. Here, I've done trial and error to set the heigth=117pt parameter (207pt by default) and the enlarge y limits=0.29 parameter. As for the width=240pt parameter, I have kept the default value.

screenshot

\documentclass[border=5mm]{standalone}
\usepackage{tikz,pgfplots}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    enlarge y limits=0.29,
    height=117pt,width=240pt,
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four}
  ]
  \addplot [fill=gray] coordinates {
    (1,One)
    (3,Two)
    (0,Three)
    (5,Four)
  };
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
  \begin{axis}[%axis equal image=true,
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten}
  ]
  \addplot [fill=gray] coordinates {
    (4,One)
    (2,Two)
    (1,Three)
    (1,Four)
    (0,Five)
    (5,Six)
    (4,Seven)
    (2,Eight)
    (2,Nine)
    (0,Ten)
  };
  \end{axis}
\end{tikzpicture}
\end{document}
1
  • That looks great, thank you. I don't have much charts to do, so I'll go with this one. Thanks again for your help. Feb 19, 2020 at 7:58
1

Welcome! This is a very simple-minded way (but still works).

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four, Five, Six, Seven, Eight, Nine,
    Ten},yticklabels={One, Two, Three, Four}
  ]
  \addplot [fill=gray] coordinates {
    (1,One)
    (3,Two)
    (0,Three)
    (5,Four)
    (0,Ten) 
  };
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
  \begin{axis}[
    xbar,
    ytick = data,
    xmin = 0, xmax = 5,
    x tick label style={opacity=0},
    ytick style = {draw=none},
    symbolic y coords = {One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten}
  ]
  \addplot [fill=gray] coordinates {
    (4,One)
    (2,Two)
    (1,Three)
    (1,Four)
    (0,Five)
    (5,Six)
    (4,Seven)
    (2,Eight)
    (2,Nine)
    (0,Ten)
  };
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

1
  • Wow. Thank you very much. That looks pretty good. Do you know if I can get something like this with the same logic? !Latex Block Feb 18, 2020 at 8:21
0

Consider using sane_tikz. The code below generates your desired figure.

enter image description here

import sane_tikz as stz
import formatting as fmt

large_data = [4, 2, 1, 1, 0, 5, 4, 2, 2, 0]
large_label_strs = [
    "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
    "Ten"
]
small_data = [1, 3, 0, 5]
small_label_strs = large_label_strs[:4]

tick_spacing = 1.0
num_ticks = 5
tick_length = 0.1
rectangle_height = 0.3
rectangle_spacing = 0.2
label_spacing = 0.1
r_fmt = fmt.fill_color('gray')
margin = 0.2

frame_width = num_ticks * tick_spacing
frame_spacing = 1.6
t_fmt = fmt.line_color('gray')


def get_ticks(e):
    top_left_cs, bottom_right_cs = stz.bbox(e)
    bottom_left_cs = stz.bottom_left_coords(top_left_cs, bottom_right_cs)
    top_ticks = []
    bottom_ticks = []
    for i in range(1, num_ticks):
        top_cs = stz.translate_coords_horizontally(top_left_cs,
                                                   i * tick_spacing)
        top_t = stz.vertical_line_segment(top_cs, -tick_length, t_fmt)
        top_ticks.append(top_t)

        bottom_cs = stz.translate_coords_horizontally(bottom_left_cs,
                                                      i * tick_spacing)
        bottom_t = stz.vertical_line_segment(bottom_cs, tick_length, t_fmt)
        bottom_ticks.append(bottom_t)
    return [bottom_ticks, top_ticks]


def bar_plot(data, label_strs):
    cs = [0, 0]
    rs = [
        stz.rectangle_from_width_and_height(cs, rectangle_height, x, r_fmt)
        for x in data
    ]

    stz.distribute_vertically_with_spacing(rs, rectangle_spacing)
    frame_height = (len(data) * rectangle_height +
                    (len(data) - 1) * rectangle_spacing + 2.0 * margin)
    frame = stz.rectangle_from_width_and_height(cs, frame_height, frame_width)
    stz.align_centers_vertically([frame, rs], 0.0)

    labels = []
    for i, r in enumerate(rs):
        l_cs = stz.coords_from_bbox_with_fn(r, stz.left_center_coords)
        l_cs = stz.translate_coords_horizontally(l_cs, -label_spacing)
        l_s = label_strs[i]
        lab = stz.latex(l_cs, l_s, fmt.anchor('right_center'))
        labels.append(lab)

    ticks = get_ticks(frame)
    return [rs, labels, frame, ticks]


e_large = bar_plot(large_data, large_label_strs)
e_small = bar_plot(small_data, small_label_strs)
stz.distribute_horizontally_with_spacing([e_small, e_large], frame_spacing)
stz.align_bottoms([e_large, e_small], 0)

stz.draw_to_tikz_standalone([e_small, e_large], "boxes.tex")

Generated tikz code:

\documentclass{standalone}
\usepackage[T1]{fontenc}\usepackage{tikz}
\usepackage{amsmath, amsfonts}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}
\draw[fill=gray] (0.000000, 0.500000) -- (1.000000, 0.500000) -- (1.000000, 0.200000) -- (0.000000, 0.200000) -- cycle;
\draw[fill=gray] (0.000000, 1.000000) -- (3.000000, 1.000000) -- (3.000000, 0.700000) -- (0.000000, 0.700000) -- cycle;
\draw[fill=gray] (0.000000, 1.500000) -- (0.000000, 1.500000) -- (0.000000, 1.200000) -- (0.000000, 1.200000) -- cycle;
\draw[fill=gray] (0.000000, 2.000000) -- (5.000000, 2.000000) -- (5.000000, 1.700000) -- (0.000000, 1.700000) -- cycle;
\node[anchor=east] at (-0.100000,0.350000) {One};
\node[anchor=east] at (-0.100000,0.850000) {Two};
\node[anchor=east] at (-0.100000,1.350000) {Three};
\node[anchor=east] at (-0.100000,1.850000) {Four};
\draw[] (0.000000, 2.200000) -- (5.000000, 2.200000) -- (5.000000, 0.000000) -- (0.000000, 0.000000) -- cycle;
\draw[draw=gray] (1.000000, 0.000000) -- (1.000000, 0.100000);
\draw[draw=gray] (2.000000, 0.000000) -- (2.000000, 0.100000);
\draw[draw=gray] (3.000000, 0.000000) -- (3.000000, 0.100000);
\draw[draw=gray] (4.000000, 0.000000) -- (4.000000, 0.100000);
\draw[draw=gray] (1.000000, 2.200000) -- (1.000000, 2.100000);
\draw[draw=gray] (2.000000, 2.200000) -- (2.000000, 2.100000);
\draw[draw=gray] (3.000000, 2.200000) -- (3.000000, 2.100000);
\draw[draw=gray] (4.000000, 2.200000) -- (4.000000, 2.100000);
\draw[fill=gray] (6.700000, 0.500000) -- (10.700000, 0.500000) -- (10.700000, 0.200000) -- (6.700000, 0.200000) -- cycle;
\draw[fill=gray] (6.700000, 1.000000) -- (8.700000, 1.000000) -- (8.700000, 0.700000) -- (6.700000, 0.700000) -- cycle;
\draw[fill=gray] (6.700000, 1.500000) -- (7.700000, 1.500000) -- (7.700000, 1.200000) -- (6.700000, 1.200000) -- cycle;
\draw[fill=gray] (6.700000, 2.000000) -- (7.700000, 2.000000) -- (7.700000, 1.700000) -- (6.700000, 1.700000) -- cycle;
\draw[fill=gray] (6.700000, 2.500000) -- (6.700000, 2.500000) -- (6.700000, 2.200000) -- (6.700000, 2.200000) -- cycle;
\draw[fill=gray] (6.700000, 3.000000) -- (11.700000, 3.000000) -- (11.700000, 2.700000) -- (6.700000, 2.700000) -- cycle;
\draw[fill=gray] (6.700000, 3.500000) -- (10.700000, 3.500000) -- (10.700000, 3.200000) -- (6.700000, 3.200000) -- cycle;
\draw[fill=gray] (6.700000, 4.000000) -- (8.700000, 4.000000) -- (8.700000, 3.700000) -- (6.700000, 3.700000) -- cycle;
\draw[fill=gray] (6.700000, 4.500000) -- (8.700000, 4.500000) -- (8.700000, 4.200000) -- (6.700000, 4.200000) -- cycle;
\draw[fill=gray] (6.700000, 5.000000) -- (6.700000, 5.000000) -- (6.700000, 4.700000) -- (6.700000, 4.700000) -- cycle;
\node[anchor=east] at (6.600000,0.350000) {One};
\node[anchor=east] at (6.600000,0.850000) {Two};
\node[anchor=east] at (6.600000,1.350000) {Three};
\node[anchor=east] at (6.600000,1.850000) {Four};
\node[anchor=east] at (6.600000,2.350000) {Five};
\node[anchor=east] at (6.600000,2.850000) {Six};
\node[anchor=east] at (6.600000,3.350000) {Seven};
\node[anchor=east] at (6.600000,3.850000) {Eight};
\node[anchor=east] at (6.600000,4.350000) {Nine};
\node[anchor=east] at (6.600000,4.850000) {Ten};
\draw[] (6.700000, 5.200000) -- (11.700000, 5.200000) -- (11.700000, 0.000000) -- (6.700000, 0.000000) -- cycle;
\draw[draw=gray] (7.700000, 0.000000) -- (7.700000, 0.100000);
\draw[draw=gray] (8.700000, 0.000000) -- (8.700000, 0.100000);
\draw[draw=gray] (9.700000, 0.000000) -- (9.700000, 0.100000);
\draw[draw=gray] (10.700000, 0.000000) -- (10.700000, 0.100000);
\draw[draw=gray] (7.700000, 5.200000) -- (7.700000, 5.100000);
\draw[draw=gray] (8.700000, 5.200000) -- (8.700000, 5.100000);
\draw[draw=gray] (9.700000, 5.200000) -- (9.700000, 5.100000);
\draw[draw=gray] (10.700000, 5.200000) -- (10.700000, 5.100000);
\end{tikzpicture}
\end{document}
1
  • 1
    Wow. Thank you @rnegrinho. I'll come back to this solution If I ever have to do more tables. Looks awesome to simply use a script to get the thing done. Feb 19, 2020 at 8:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .