1

I want to generate a stacked graph with matplotlib, and I want to use wiggle option. For example:

import matplotlib.pyplot as plt

vals = [[0, 1, 1, 2, 3],  [0, 0, 2, 4, 4],  [1, 1, 2, 2, 2]]
xs = [0, 1, 2, 3, 4]
plt.stackplot(xs, vals, baseline='wiggle')
plt.show()

This draws something like this:

enter image description here

But I want something more (not necessary exactly) like this:

enter image description here

My problem is, that on y-axis there are negative values. This is the result of using baseline='wiggle', but I need to use wiggle, because with zero, the plot is not clear and readable enough.

The y-values or thickness/width of the whole stackplot is the main reason why I'm making the graph, so I'd like to show that at the end, the thickness/width of the whole plot is 9.

What I want:

  • to indicate whole stackplot thickness/width at several x-positions (5 should be ok)
  • to keep the graph as clean and simple as possible
  • solution should be simple (otherwise it's simpler to "draw" numbers on finished graph manually)

What I don't want (need):

  • negative values on y-axis
  • I don't need exactly the same look as in the picture above, I just need some way of indicatin thickness/width..

What I tried:

  • using baseline='zero' - the graph is too confusing, can't use zero
  • deleting y-ticks (plt.yticks([], [])) and adding annotations manually - this means I have to create annotations every time data changes. And it looks just ugly.

Is there any other simple way how to display whole stackplot thickness/width in a meaningful way?

Also, I'm ok with "no, there is no simple way of doing this, either you have to write it yourself or do it manually" answer.

Jan Spurny
  • 5,219
  • 1
  • 33
  • 47
  • Can you do the math on your min/max values for each data point, then pass it into a list of [vlines](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.vlines.html) as ymin, ymax? – G. Anderson Nov 06 '18 at 19:02
  • @G.Anderson - yes I could, I was just trying to find out if there is some easier way than doing it "manually". I'm pretty sure I'm not the first one who doesn't like the negative y-values.. – Jan Spurny Nov 06 '18 at 19:06
  • Also, the "something like this" image I posted is quite ugly - so I was hoping there may be some "cleaner" way too.. – Jan Spurny Nov 06 '18 at 19:07
  • It's a nitpick, but if you wrap it in a function, then it's no longer "manual". When you say manual, I assume you mean going in and adding them one-by-one in each plot. I would say using vlines is "programmatic", but I don't believe there is a _built-in_ way to do what you're asking. You might be able to do something like adding [axis labels at the top](https://stackoverflow.com/questions/14406214/moving-x-axis-to-the-top-of-a-plot-in-matplotlib). FWIW, I think the second plot you showed is very readable and useful. – G. Anderson Nov 06 '18 at 19:17
  • I guess you knew from the start that there is no magic `make_plot_as_I_like_it()` function. So I wonder what this question really asks about. Note that you may of course share a paintbrush picture or similar to convey how you want your graph to look like. – ImportanceOfBeingErnest Nov 06 '18 at 20:55
  • @G.Anderson: - I meant "manually" as in "I have to write it myself" instead of (hypothetical) built-in `display_stacked_width = on` magical option. @ImportanceOfBeingErnest: you're right (see question's last sentence), but I have encountered matplotlib _hacks/cool features_ which were a bit unclear from documentation until I saw them used somewhere. So I was hoping this may have been another such case. Btw - do you think I should delete the question? – Jan Spurny Nov 07 '18 at 00:11
  • Re: Deleting the question: Personally, I would try to find a solution you're happy with, even if it's more 'manual' than you'd like, and add it as an answer in case someone else down the line has the same question. But if you're going to pursue other plotting options, I'd consider deleting. – G. Anderson Nov 07 '18 at 15:45

0 Answers0