How can I plot attached three interrelated stacked bars and separately style as well as label their partially recurring block components?

Dear all,
I would like to visualize three decompositions by creating a graph with three stacked bar plots. I attach a schematic drawing of what I have in mind (and apologize for the format - I hope this makes it clearer than some lengthy explanation).
I have created stacked bar plots in the past, but what makes it complex / too hard for me is that
a) the blocks are interrelated across the decompositions A, B, C (e.g. block "b" turns up in decompositions A and C)
b) the separate styling and the labeling of the blocks
c) the labeling of the three stacked bars as "A", "B", "C".
Is there a way to insert the stacked bars next to each other, creating and labeling them independently but making matlab recognize the repeated occurrence of the block elements when it creates the legend?
I would be really grateful for any advice! Thank you

 Accepted Answer

Extending dpb's answer below by using the user-written function applyhatch_plusC (along with its extension makehatch_plus, under the same link), I managed to get this result:
using the following code:
y = [5 2 0 4 0 0
5 0 3 0 3 0
5 2 0 0 3 1];
x=categorical({'A';'B';'C';'D'});
bar(x(1:3),y,'stacked')
legend(cellstr(['a':'f'].'),'Location','northeast')
xticks(x(1:3))
im_hatchC = applyhatch_plusC(gcf,{makehatch_plus('\\7',9),makehatch_plus('//7',9),makehatch_plus('//7',3),makehatch_plus('//7',9),makehatch_plus('\\7',9),makehatch_plus('//7',3)},[1 0 0;0 0 1;0 0 0;1 0 0;0 0 1;0 1 0]);
Not optimal (given the pixeled numbers, not only in attached image but in the original output as well - if somebody knows a solution to this please leave a comment) but possibly sufficient

3 Comments

The description for applyhatch_plusC says it "creates a bitmap version of the defined figure..." so there's where the pixelated image will have come from. It seems in looking that's been the way all these submissions have been approached -- they don't actually draw the hatching but replace the area with the effective image pixels.
That's why the support needs to be built into the HG2 engine itself...plus being able to get to all the stuff that's hidden to make work transparently with legend, etc., etc., etc., ...
Ah ok, that's the reason! I don't know the specifics about bitmaps or other formats when it comes to figures, but it doesn't sound like there's an easy workaround for that I guess... so for now I will take it as it is! But again, I do agree that hatching patterns and the access to the legend should be included features.
The problem is that to actually render the hatching patterns is a lot of calculations/work -- you have to have the boundaries of each area(*) and physically draw lines (programatically). It's much simpler to create a pattern and just replace the area at the cost of the resolution and so on.
When you create an area and then add more lines on it, the way HG works is that each and every one of those lines is a new, separate line handle unless all the coordinates are computed first and they're drawn as one line...either way, to legend the result is then an area and multiple lines/graphic objects handles, not a composite object that is the actual hatching pattern. Hence, legend() will create a new legend for each element; it doesn't know anything at all about the effect one is trying to create; they're all just independent areas/lines, each to be labelled on its own.
There needs, instead, to be an actual hatching object/property added to the base object space of HG objects/properties; it's the only way to ever make a really clean facility. Why it was not part of the base design when HG2 was invented is beyond my comprehension -- it's so fundamental a concept.
(*) And this is further complicated in case such as this where the X axis is a categorical variable for which one doesn't have the actual coordinates of the bars in the x-axis direction because while the line primitive does know about a categorical variable, there are only integral values from 1:N categories available in that coordinate system; there's no such thing as 'A' +/-80%(Difference 'B' - 'A') to use to limit the hatching line coordinates to within the specific bar.
At the user-code level one would have to resort to overlaying a second axes and doing the drawing on it instead because the CategoricalRuler axis object will only accept categorical values against the x-axis. So, while the hidden 'Face.VertexData' property does contain the same coordinates whether the x-axis is categorical or with the same data plotted against numeric 1:3 range, there's no way to make use of it if the axis is categorical; the CategoricalRuler object just won't let you pass anything else in. One would have to have access to the base properties at the internal level to be able to draw on the bars themselves.

Sign in to comment.

More Answers (1)

Use something like
y = [5 2 0 4 0 0
5 0 3 0 3 0
5 2 0 0 3 1];
x=categorical({'A';'B';'C';'D'});
bar(x(1:3),y,'stacked')
legend(cellstr(['a':'f'].'),'Location','northeast')
xticks(x(1:3))
to produce
Unfortunately, default colors are awful and we still don't have builtin hatching patterns so you'll have to work to set some less garish colors...
NB: the "trick" is each row in an array is a bar for a stacked plot; each column is the set of variable values for the bar; zero is a valid value (as is NaN for some special effects especially valuable).
NB Second: The extra category for the x axis to provide the room for the legend inside and then don't display the tick for it.

7 Comments

Thank you so much! This is very helpful already and I would never have gotten this far by myself.
Just one thing, however: For the message of the graph it is essential that there are the two types of visual links between the blocks - the color and the hatching (or similar) pattern.
For example, I not only need the link by the hatching pattern between the two "b" blocks in bars A and C in my drawing, but I also need the color link between the "b" blocks and the "c" block.
Is there any way how one could implement this? Thanks again for your effort!
A MAJOR shortfall in MATLAB I've railed about along with bar itself for 30 years...
<Selecting-or-setting-hatching-patterns> was my first attempt after the Answers forum was opened; I'd been after TMW for years prior until finally just gave it up as lost cause...as I've pointed out to them we had them on CalComp pen plotters in the 60s and 70s and still don't exist in MATLAB????
<Answer_916574> seems to be a recent incarnation of one of the FileExchange submittals that looks like were able to get to work...I've not done anything recently in the area, specifically. I do NOT know how nicely this plays with legend(); back when my original post was made, several of the submittals at the time wouldn't reflect the hatch in the legend automagically; you had to manually hatch those to match. But, back then you had full access to the handles of the axes object from which the legend was constructed, now they've taken that facility away by making it almost opaque to user customization. You'll just have to experiment. All in all, it's a disaster of an area and an embarrassment and a major time waster for MATLAB users. As the comments there indicate, at that time all submittals on File Exchange had serious warts/shortcomings in some area; there was nothing available that "just worked" seamlessly. That was right at the HG1/HG2 transition time which didn't help any, but the basic routines at the time were also just not yet production-quality code.
Add your voice in the wilderness to enhancement requests -- they should be built into the base functions at the basic level of HG2.
Thanks a lot, dpb, for this insight! Wow, I didn't expect it to be this complicated - it does not seem to be such a specific feature indeed, to add both hatching and color to bars. In any case, it seems I met just the right person to get an impression of the problem.
I have to admit that I don't know anything about HG1 or HG2. I might give it a try with the sources you mentioned, and "experiment". But given the headache that this issue seems to have caused to you and others, I might just manually export the data and try it in a different environment, even though that's annoying. Perhaps CalComp then :P
Agreed, it definitely should NOT be complicated at all; you should be able to just set a hatching property directly with a named parameter/pattern value pair.
However, despite my obvious displeasure/frustration w/ TMW over the issue, I still suggest using the second link to the File Exchange submission and give it a shot -- if it works well, shouldn't take longer than to export and do it elsewhere.
You don't need to be concerned about HG1/HG2; that's now history; everything now is HG2 -- TMW totally revamped the graphics subsystem back ages ago now (I forget just when but by now ancient history in version-time-frames) so you're not going to run into HG1 stuff now. That's why the second link is the one that I posted -- it is at least one submittal that is current and seemed to work although I haven't tried it myself. The only caution is that an unwary search of FileExchange could possibly lead to some older submittals still.
Hi dpb, thanks to your advice and using applyhatch_plusC I managed to produce something satisfactory that I'd like to post here. Since I am quite new to the forum: what's the best practice? Should I create a different answer, posting my solution (of course crediting your answer in the text) and accept my own answer, or should I post it as a further comment under this, i.e. your answer, and accept this answer (which is only complete with our comments underneath)? Thanks
I'd suggest an Answer to the Q? here -- it would keep context together and by being Answer indicates a solution to the problem/Q? raised...
There's nothing wrong imo of answering your own Q? either by discovering something new on your own or with assistance, the point is to get to a satisfactory solution with, hopefully, a byproduct that somebody else may find useful and while not an official support site, some feedback that may help influence futher development.

Sign in to comment.

Categories

Asked:

on 7 May 2022

Edited:

dpb
on 8 May 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!