Skip to content

[Feature request] Functions for "manually" plotting histograms #6669

Description

@smheidrich

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.

Activity

  1. story645 commented on Jun 30, 2016

    @story645
    Member

    How is what you're asking for different from passing in the already supported bin kwarg?

    hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, **kwargs)
    
    hist2d(x, y, bins=10, range=None, normed=False, weights=None, cmin=None, cmax=None, **kwargs)
    

    bins can be an array or list of bins, not just an integer.

  2. WeatherGod commented on Jun 30, 2016

    @WeatherGod
    Member

    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:

    How is what you're asking for different from passing in the already
    supported bin kwarg?

    hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, **kwargs)

    hist2d(x, y, bins=10, range=None, normed=False, weights=None, cmin=None, cmax=None, **kwargs)

    bins can be an array or list of bins, not just an integer.

    —
    You are receiving this because you are subscribed to this thread.
    Reply to this email directly, view it on GitHub
    #6669 (comment),
    or mute the thread
    https://github.com/notifications/unsubscribe/AARy-AI2JA2qvd4HQctKiiqjAy3IJbIlks5qRBlKgaJpZM4JCCfT
    .

  3. story645 commented on Jun 30, 2016

    @story645
    Member

    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.

  4. smheidrich commented on Jul 1, 2016

    @smheidrich
    ContributorAuthor

    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).

  5. story645 commented on Jul 1, 2016

    @story645
    Member

    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?

  6. smheidrich commented on Jul 1, 2016

    @smheidrich
    ContributorAuthor

    I'll try, unless someone who is more qualified "feels motivated" :)

  7. story645 commented on Jul 1, 2016

    @story645
    Member

    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)

  8. added this to the milestone on Jul 1, 2016
  9. tacaswell commented on Jul 1, 2016

    @tacaswell
    Member

    👍 This is something that needs to be done

  10. modified the milestones: , on Oct 3, 2017
  11. HDembinski commented on Feb 15, 2019

    @HDembinski

    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.

  12. HDembinski commented on Feb 15, 2019

    @HDembinski

    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.

  13. chrisburr commented on Feb 15, 2019

    @chrisburr

    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.histogram
    pyplot.hist(*numpy.histogram(data), prebinned=True)
    # Multiple histograms can be stacked
    pyplot.hist([counts_1, counts_2,  counts_3], bins=bins, prebinned=True, stacked=True)
  14. 43 remaining items

  15. anntzer commented on Feb 19, 2019

    @anntzer
    Contributor

    Thank you for the detailed examples.

    I'll note, in passing, that your comment re:

    fig, ax = plt.subplots()
    ax.step(edges, np.r_[bkg_freq, 0], where='post')
    

    "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).

  16. nsmith- commented on Feb 19, 2019

    @nsmith-

    @anntzer I think my phrasing was misleading. I agree, we do not want it to go to zero.

  17. HDembinski commented on Feb 20, 2019

    @HDembinski

    @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.

  18. nsmith- commented on Feb 20, 2019

    @nsmith-

    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.

  19. HDembinski commented on Feb 22, 2019

    @HDembinski

    I think I understood you correctly and my own opinion has evolved to the point that I would also favor this solution.

  20. tacaswell commented on Feb 23, 2019

    @tacaswell
    Member

    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).

  21. HDembinski commented on Feb 24, 2019

    @HDembinski

    @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?

  22. HDembinski commented on Feb 27, 2019

    @HDembinski

    @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!

  23. modified the milestones: needs sorting, v3.4.0 on Sep 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions