You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature request] Functions for "manually" plotting histograms #6669
matplotlib's pyplot.hist and pyplot.hist2d functions fill the supplied data into histogram bins and plot them, but very often users will have already done the first step (sorting data into bins) in their own code and are merely interested in presenting their results in a "style" that is evocative of histograms (most commonly: bar chart with no separation for 1D data, colored grid for 2D data).
Right now they can do this by using the pyplot.bar and pyplot.imshow functions for 1D and 2D data, respectively, but they have to fill in a bunch of arguments to make it look like something produced by pyplot.hist or pyplot.hist2d and they have to find out that those two are the right functions for the job in the first place (not very intuitive).
Hence I think it would be good if there were separate functions or maybe just special arguments to pyplot.hist/hist2d that allow you to plot bin values (as opposed to data that is yet to be binned) as histograms that look exactly as if they had been produced by pyplot.hist/hist2d.
It is (slightly) different because the OP isn't asking for the ability to
pass in a list of bins at which to operate at, but rather to pass in the
resulting histogram along with the bins.
We probably should look into refactoring hist/hist2d a bit so that those
functions are composed of a data-prep step and then a data display step.
Those steps could probably become user-facing functions in their own right
(in their own module... not in axes or pyplot) which advanced users could
access themselves if they want to bypass one step or the other.
Had a look at hist and it seems really entangled and I wonder if part of the refactoring should be pitching the display to bar & line2d and others with the customization needed for hist.
Correct me if I'm wrong, but to me it seems like this line pretty much marks the border between data preparation and display logic. n contains the histogram-processed data ("bin height") to be plotted, and that is what I would like the user to be able to supply directly (in addition to bins, of course).
Kind of. There's some stuff early on about plot type and other display logic early on and there's stuff like conversion logic that's important for both, as are some of the cbook calls.
That being said, would you be motivated to factor out the computation logic?
You're perfectly qualified to do it! You're motivated, you grok the problem & the solution, and you mostly know where to start. If you sort it out in a less than matplotlibish way, the devs will tell you on the PR. (And you can always ask on the gitter)
Hi, what's the status on this? Maybe it is possible to just improve the docs? Ideally, one should be able to pass the output of numpy.histogram to this hist, because it is a standard in the python world and other histogramming libraries usually support it as well.
Reacted by Matthieu Marinangeli, Jonas Eschle, Chris Burr, Henry Schreiner, jkopp and Richard Higgins
Possible implementation: if the x argument of hist is getting a tuple with two sequences N+1 and N, then interpret this as the numpy output.
This is potentially ambiguous as pyplot.hist can already plot multiple histograms in one call (independently or stacked). How about adding a keyword argument like prebinned:
pyplot.hist(counts, bins=bins, prebinned=True)
# It also supports using the output of numpy.histogrampyplot.hist(*numpy.histogram(data), prebinned=True)
# Multiple histograms can be stackedpyplot.hist([counts_1, counts_2, counts_3], bins=bins, prebinned=True, stacked=True)
"Note that it does not cause the line to go to zero at the end, as we want--we have no information about this empirical PDF outside the specified binning." actually argues against automatically moving to zero at the end of the step plot, as that may be undesirable (although I'd guess most often that's what people do want).
Also, note that np.r_[x, 0] can now be spelled [*x, 0] (which is in theory a bit slower as the looping is no longer done through numpy, but in practice that's going to be insignificant compared to other slowdowns imposed by matplotlib while it goes through the data).
@nsmith- The irregularities are why OP, myself, and also apparently @tacaswell want to have a first class plotting utility for histograms, which does what step and fill_between does but without the extra jumps. It should not include functionality provided by errorbar, because that's really a different kind of plot in my view and errorbar is fine as it is.
Like @jklymak, I believe that preparing the data should be separate from plotting it and I prefer low-level functions which just do the plotting.
So instead of making hist more complex, one could also try to extend step and fill_between so that they work better with pre-binned data. I really don't know at this point which route is better. I think @tacaswell said elsewhere that small functions with a narrow focus are preferred, which would mark hist as a historic mistake that shouldn't be made even worse by shoehorning more functionality into it (which is also a view expressed by @anntzer). I think this needs guidance from the core devs.
Ok, well my suggestion (which maybe isn't clear from the post) is a small change to step and fill_between that allows specifying edges and some syntax like step='edges'. After that, the interface is quite clean. For errorbar it would also be nice to have that, but I understand this might be a harder sell since one can first draw the step and then overlay a simple errorbar on centers to recreate the hack that I demonstrated.
@tacaswell That's great news, because we von Scikit-HEP are working on that. This would be a large project, but as a short-term solution it would be useful to extend pyplot.step and pyplot.fill_between to work better with pre-binned data. This could be done with a single PR with a mild change, I think, what do you think about this?
Activity
story645 commentedon Jun 30, 2016
How is what you're asking for different from passing in the already supported bin kwarg?
bins can be an array or list of bins, not just an integer.
WeatherGod commentedon Jun 30, 2016
It is (slightly) different because the OP isn't asking for the ability to
pass in a list of bins at which to operate at, but rather to pass in the
resulting histogram along with the bins.
We probably should look into refactoring hist/hist2d a bit so that those
functions are composed of a data-prep step and then a data display step.
Those steps could probably become user-facing functions in their own right
(in their own module... not in axes or pyplot) which advanced users could
access themselves if they want to bypass one step or the other.
On Thu, Jun 30, 2016 at 3:30 PM, hannah [email protected] wrote:
story645 commentedon Jun 30, 2016
Thanks for clarifying.
Had a look at hist and it seems really entangled and I wonder if part of the refactoring should be pitching the display to bar & line2d and others with the customization needed for hist.
smheidrich commentedon Jul 1, 2016
Correct me if I'm wrong, but to me it seems like this line pretty much marks the border between data preparation and display logic.
ncontains the histogram-processed data ("bin height") to be plotted, and that is what I would like the user to be able to supply directly (in addition tobins, of course).story645 commentedon Jul 1, 2016
Kind of. There's some stuff early on about plot type and other display logic early on and there's stuff like conversion logic that's important for both, as are some of the cbook calls.
That being said, would you be motivated to factor out the computation logic?
smheidrich commentedon Jul 1, 2016
I'll try, unless someone who is more qualified "feels motivated" :)
story645 commentedon Jul 1, 2016
You're perfectly qualified to do it! You're motivated, you grok the problem & the solution, and you mostly know where to start. If you sort it out in a less than matplotlibish way, the devs will tell you on the PR. (And you can always ask on the gitter)
tacaswell commentedon Jul 1, 2016
👍 This is something that needs to be done
HDembinski commentedon Feb 15, 2019
Hi, what's the status on this? Maybe it is possible to just improve the docs? Ideally, one should be able to pass the output of
numpy.histogramto thishist, because it is a standard in the python world and other histogramming libraries usually support it as well.HDembinski commentedon Feb 15, 2019
Possible implementation: if the x argument of
histis getting a tuple with two sequences N+1 and N, then interpret this as the numpy output.chrisburr commentedon Feb 15, 2019
This is potentially ambiguous as
pyplot.histcan already plot multiple histograms in one call (independently or stacked). How about adding a keyword argument likeprebinned:43 remaining items
anntzer commentedon Feb 19, 2019
Thank you for the detailed examples.
I'll note, in passing, that your comment re:
"Note that it does not cause the line to go to zero at the end, as we want--we have no information about this empirical PDF outside the specified binning." actually argues against automatically moving to zero at the end of the step plot, as that may be undesirable (although I'd guess most often that's what people do want).
Also, note that
np.r_[x, 0]can now be spelled[*x, 0](which is in theory a bit slower as the looping is no longer done through numpy, but in practice that's going to be insignificant compared to other slowdowns imposed by matplotlib while it goes through the data).nsmith- commentedon Feb 19, 2019
@anntzer I think my phrasing was misleading. I agree, we do not want it to go to zero.
HDembinski commentedon Feb 20, 2019
@nsmith- The irregularities are why OP, myself, and also apparently @tacaswell want to have a first class plotting utility for histograms, which does what
stepandfill_betweendoes but without the extra jumps. It should not include functionality provided byerrorbar, because that's really a different kind of plot in my view anderrorbaris fine as it is.Like @jklymak, I believe that preparing the data should be separate from plotting it and I prefer low-level functions which just do the plotting.
So instead of making
histmore complex, one could also try to extendstepandfill_betweenso that they work better with pre-binned data. I really don't know at this point which route is better. I think @tacaswell said elsewhere that small functions with a narrow focus are preferred, which would markhistas a historic mistake that shouldn't be made even worse by shoehorning more functionality into it (which is also a view expressed by @anntzer). I think this needs guidance from the core devs.nsmith- commentedon Feb 20, 2019
Ok, well my suggestion (which maybe isn't clear from the post) is a small change to
stepandfill_betweenthat allows specifying edges and some syntax likestep='edges'. After that, the interface is quite clean. Forerrorbarit would also be nice to have that, but I understand this might be a harder sell since one can first draw thestepand then overlay a simpleerrorbaron centers to recreate the hack that I demonstrated.HDembinski commentedon Feb 22, 2019
I think I understood you correctly and my own opinion has evolved to the point that I would also favor this solution.
tacaswell commentedon Feb 23, 2019
re-opened this as it was automatically closed by merging a docs PR.
I think a library of helper functions tuned to HEP would also be a good idea (and something I would be happy to host under the matplotlib github org).
HDembinski commentedon Feb 24, 2019
@tacaswell That's great news, because we von Scikit-HEP are working on that. This would be a large project, but as a short-term solution it would be useful to extend
pyplot.stepandpyplot.fill_betweento work better with pre-binned data. This could be done with a single PR with a mild change, I think, what do you think about this?HDembinski commentedon Feb 27, 2019
@tacaswell The Scikit-HEP group would like to invite you and anyone else interested in discussing a HEP plotting module in matplotlib over to https://gitter.im/HSF/mpl-hep for further discussion on how to proceed with this project. Thank you!