My histogram is having a Regular
and a strCategory
axis and I want to show the cumulative sum of the categories, but with the different components stacked on top of each other.
I found out I can just use np.cumsum(axis=<category axis>)
to calculate the cumulative sum and create a new histogram from that. In had also managed to draw a stacked histogram by plotting multiple plt.bar
with different bottom=...
arguments taken from the cumulative sums. But I dislike that visualy, because I want to have a black outline for my components, but no outlines for the individual bins, as seen in the screenshot.
Hi, I used to be able to modify histogram contents like this
import boost_histogram as bh
import numpy as np
bins = [0, 1, 2]
hist = bh.Histogram(bh.axis.Variable(bins), storage=bh.storage.Weight())
yields = [3, 4]
var = [0.1, 0.2]
hist[...] = np.stack([yields, var], axis=-1)
hist.view().value /= 2
That worked until boost-histogram
version 0.11.1
. In the current master it does not anymore, I think scikit-hep/boost-histogram#475 changes the behavior:
Traceback (most recent call last):
File "test.py", line 10, in <module>
hist.view().value /= 2
File "[...]/boost_histogram/_internal/view.py", line 57, in fset
self[name] = value
File "[...]/boost_histogram/_internal/view.py", line 49, in __setitem__
raise ValueError("Needs matching ndarray or n+1 dim array")
ValueError: Needs matching ndarray or n+1 dim array
Is there another way to achieve this now?
hist.view() /= 2
.
python-3.8
package, you still get pip 9 even on Python 3.8!!! (which is totally unsupported). I hate distro packaging sometimes…
Congratulations on boost-histogram
1.0! I'm adopting the new API for subclassing, and saw in https://boost-histogram.readthedocs.io/en/latest/usage/subclassing.html that family=object()
is recommended when only overriding Histogram
. What is the difference between object()
and object
? While trying to understand this, I noticed that object is object
is True
and object() is object()
(are those instances?) is False
. Is the latter part an issue given the following?
It just has to support is, and be the exact same object on all your subclasses.
object
is a class; classes are singletons, there’s just one. object()
is an instance, and you can make as many as you want, each will live in a different place in memory, check with id()
. Basically, family=
can be anything that supports is which is literally everything, with the exception of the Module boost_histogram
(as that’s already taken by boost-histogram). The Module hist
would be a bad choice too, as then your axes would come out randomly Hist's or your own. The old way works fine, FAMILY = object()
at the top of the file, then use family=FAMILY
when you subclass. But for most users, a handy existing object is the module you are in, that is, “hist” or “boost_histogram”. It’s unique to you, and is descriptive. You can use family=None
(or the object class, anything works), you just don’t want some other extension to also use the same one - then boost-histogram won’t be able to distinguish between them when picking Axis, Storage, etc. If all you use is Histogram, though, then it really doesn’t matter.
object()
is to make a truly unique object. For example, if I make NOTHING=object()
, then use def f(x =NOTHING): if x is NOTHING
, I can now always tell if someone passed a keyword argument in. They can’t make NOTHING, they have to pull NOTHING out of my source and using it from there, you can’t “remake” it accidentaly.
The ideal way would have been the following:
class Hist(bh.Histogram): …
class Regular(bh.axis.Regular, parent=Hist)
The problem with this would have been it is very hard to design without circular imports, as Histogram almost always has Axis usages in it. It can be done, but would have requried changes to boost-histogram and user code, which also has to follow this strict regimen. Using a token is much simpler; it doesn’t require as much caution in user code (or boost-histogram).
Histogram
would create a new object()
and then not match the object()
in the family definition, but from what I understand now this is not what happens - this object is created once when the class is defined, and any other class that may also inherit defined in my code with family=object()
would pick up a different object and be unique too.