0

I am trying to create a stacked bar plot while marking (connected) parts of it.

The axis cs approach seems to work in this case, but there are two problems which I am facing:

  1. The outline is mostly invisible. I tried experimenting with pgfonlayer, but without success. I want it to be visible completely.

  2. The outline is too small. It matches the xticks, but not the ybar area itself which looks a bit odd.

How can I fix these problems?

This is my current code:

\documentclass[border=2mm]{standalone}

\usepackage{pgfplots}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.15}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[%
        ybar stacked,
        width=4cm,
        height=4cm,
        date coordinates in=x,
        xticklabel={\minute},
        xmin={2020-04-21 15:00},
        xmax={2020-04-21 15:10},
        ymin=0,
        ymax=3,
        enlarge y limits=0.025,
        enlarge x limits=0.1,
        xtick={2020-04-21 15:00,2020-04-21 15:10},
    ]
    \addplot+[%
        draw=none,
    ] coordinates {
        ({2020-04-21 15:00},0)
        ({2020-04-21 15:01},1)
        ({2020-04-21 15:02},1)
        ({2020-04-21 15:03},1)
        ({2020-04-21 15:04},1)
        ({2020-04-21 15:05},1)
        ({2020-04-21 15:06},0)
        ({2020-04-21 15:07},0)
        ({2020-04-21 15:08},0)
        ({2020-04-21 15:09},1)
        ({2020-04-21 15:10},1)
    };
    \addplot+[%
        draw=none
    ] coordinates {
        ({2020-04-21 15:00},0)
        ({2020-04-21 15:01},1)
        ({2020-04-21 15:02},1)
        ({2020-04-21 15:03},1)
        ({2020-04-21 15:04},0)
        ({2020-04-21 15:05},0)
        ({2020-04-21 15:06},1)
        ({2020-04-21 15:07},1)
        ({2020-04-21 15:08},0)
        ({2020-04-21 15:09},0)
        ({2020-04-21 15:10},0)
    };

    \draw[densely dotted,thick] (axis cs:{2020-04-21 15:01},0) rectangle (axis cs:{2020-04-21 15:05},1);
    \end{axis}
\end{tikzpicture}

\end{document}

current output

3
  • I tried to play a bit with the calc library and the bar widths, but I guess the compatibility is not complete with the datetime library – BambOo Apr 21 '20 at 17:09
  • Problem 1 is, because stacked plots are drawn in reverse order. So just move the \draw command before the first \addplot command. There is no need for layers. Problem 2 is already solved by BambOo's answer. – Stefan Pinnow Apr 21 '20 at 18:06
  • Thanks for the hint regarding the drawing order. But the linked answer does not provide a real solution to the second problem for now, as it still says that there are computation errors. While doing some additional experiments based on BambOo's explanation I was able to get it to work using ($(axis cs:{2020-04-21 15:01},0)-(\pgfplotbarwidth/2,0pt)$) rectangle ($(axis cs:{2020-04-21 15:05},1)+(\pgfplotbarwidth/2,0pt)$). Feel free to add an answer. – epR8GaYuh Apr 21 '20 at 18:17
2

The first point can be solved using layers, see e.g. here for instance. My proposal directly comes from there. The second point is due to the bar width that is not accounted for. You can see this if you increase the size of the plot. I wanted to shift the rectangle points with \pgfplotbarwidth , but the computation seems to fail because of the dates, and I could not figure why.

Hope this gives information for someone else to solve this.

\documentclass[border=2mm]{standalone}

\usepackage{pgfplots}
\usetikzlibrary{calc}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.15}
% From https://tex.stackexchange.com/a/350514/141947
\pgfplotsset{
    % define the layers you need.
    % (Don't forget to add `main' somewhere in that list!!)
    layers/my layer set/.define layer set={
        background,
        main,
        foreground
    }{
        % you could state styles here which should be moved to
        % corresponding layers, but that is not necessary here.
        % That is why wo don't state anything here
    },
    % activate the newly created layer set
    set layers=my layer set,
}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[%
        ybar stacked,
        width=10cm,
        height=10cm,
        date coordinates in=x,
        xticklabel={\Hour:\minute},
        xmin={2020-04-21 15:00},
        xmax={2020-04-21 15:10},
        ymin=0,
        ymax=3,
        enlarge y limits=0.025,
        enlarge x limits=0.1,
        bar width=5mm
        %xtick={2020-04-21 15:00,2020-04-21 15:10},
    ]
    \addplot+[%
    on layer=background,
        draw=none,
    ] coordinates {
        ({2020-04-21 15:00},0)
        ({2020-04-21 15:01},1)
        ({2020-04-21 15:02},1)
        ({2020-04-21 15:03},1)
        ({2020-04-21 15:04},1)
        ({2020-04-21 15:05},1)
        ({2020-04-21 15:06},0)
        ({2020-04-21 15:07},0)
        ({2020-04-21 15:08},0)
        ({2020-04-21 15:09},1)
        ({2020-04-21 15:10},1)
    };
    \addplot+[%
    on layer=background,
        draw=none
    ] coordinates {
        ({2020-04-21 15:00},0)
        ({2020-04-21 15:01},1)
        ({2020-04-21 15:02},1)
        ({2020-04-21 15:03},1)
        ({2020-04-21 15:04},0)
        ({2020-04-21 15:05},0)
        ({2020-04-21 15:06},1)
        ({2020-04-21 15:07},1)
        ({2020-04-21 15:08},0)
        ({2020-04-21 15:09},0)
        ({2020-04-21 15:10},0)
    };
    \draw[densely dotted,thick,on layer=foreground] (axis cs:{2020-04-21 15:01},0) rectangle (axis cs:{2020-04-21 15:05},1);
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

EDIT

Here is an updated version, I believe there are missing interfaces between bar plots and datetime. Specifically one should be able to use a unit for bar width which fails in this case. So I played a bit with values to obtain something correct. Use (+/-\pgfplotbarwidth/2,0pt) shifts to account for the bar width. Pay attention to use 0pt and not 0 otherwise the compilation fails.

\documentclass[border=2mm]{standalone}

\usepackage{pgfplots}
\usetikzlibrary{calc}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.15}
% From https://tex.stackexchange.com/a/350514/141947
\pgfplotsset{
    % define the layers you need.
    % (Don't forget to add `main' somewhere in that list!!)
    layers/my layer set/.define layer set={
        background,
        main,
        foreground
    }{
        % you could state styles here which should be moved to
        % corresponding layers, but that is not necessary here.
        % That is why wo don't state anything here
    },
    % activate the newly created layer set
    set layers=my layer set,
}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[%
        ybar stacked,
        width=4cm,
        height=4cm,
        date coordinates in=x,
        xticklabel={\Hour:\minute},
        xmin={2020-04-21 15:00},
        xmax={2020-04-21 15:10},
        ymin=0,
        ymax=3,
        enlarge y limits=0.025,
        enlarge x limits=0.1,
        bar width=2.1mm,
        bar shift=0*\pgfplotbarwidth/2,
        xtick=data,
        xtick={2020-04-21 15:00,2020-04-21 15:10},
    ]
    \addplot+[%
    on layer=background,
        draw=none,
    ] coordinates {
        ({2020-04-21 15:00},0)
        ({2020-04-21 15:01},1)
        ({2020-04-21 15:02},1)
        ({2020-04-21 15:03},1)
        ({2020-04-21 15:04},1)
        ({2020-04-21 15:05},1)
        ({2020-04-21 15:06},0)
        ({2020-04-21 15:07},0)
        ({2020-04-21 15:08},0)
        ({2020-04-21 15:09},1)
        ({2020-04-21 15:10},1)
    };
    \addplot+[%
    on layer=background,
        draw=none
    ] coordinates {
        ({2020-04-21 15:00},0)
        ({2020-04-21 15:01},1)
        ({2020-04-21 15:02},1)
        ({2020-04-21 15:03},1)
        ({2020-04-21 15:04},0)
        ({2020-04-21 15:05},0)
        ({2020-04-21 15:06},1)
        ({2020-04-21 15:07},1)
        ({2020-04-21 15:08},0)
        ({2020-04-21 15:09},0)
        ({2020-04-21 15:10},0)
    };
    \draw[densely dotted,thick,on layer=foreground] ($(axis cs:{2020-04-21 15:01},0) + (-\pgfplotbarwidth/2,0pt)$) rectangle ($(axis cs:{2020-04-21 15:05},1) + (\pgfplotbarwidth/2,0pt)$);
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

11
  • It seems like ($(axis cs:{2020-04-21 15:01},0)-(\pgfplotbarwidth/2,0pt)$) rectangle ($(axis cs:{2020-04-21 15:05},1)+(\pgfplotbarwidth/2,0pt)$) works for the rectangle. Found this while doing some experiments based on your explanation. – epR8GaYuh Apr 21 '20 at 18:20
  • @epR8GaYuh yep, it works indeed. I tried with a 0 not 0pt yshift. Thanks fo the feedback. I really think something is broken between datetime and bar plots – BambOo Apr 21 '20 at 19:36
  • @BambOo, feel free to add an issue to the PGFPlots repository (which has moved to GitHub). It is absolutely possible that there is a missing interface between bar plots and the datetime library. – Stefan Pinnow Apr 25 '20 at 17:02
  • @StefanPinnow Thanks for the update on the new repository. However (and unfortunately) the last issues I posted are still not solved (already related to bar plots) so maybe you are a bit occupied at the moment. – BambOo Apr 25 '20 at 20:36
  • @BambOo, I am sorry. Although I am member of the developers I am just the "helper" guy to keep a bit track of stuff. But unfortunately I am unable to program in (La)TeX ... Also when there seems to be almost zero activity in the PGFPlots development that shouldn't mean people should stop reporting issues. And of course if the solution is already known also this should be either stated in the issue or even better be placed as a pull request. Thank you in advance for filing the issue ;) – Stefan Pinnow Apr 25 '20 at 22:06

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.