scikit-hep / histbook

Versatile, high-performance histogram toolkit for Numpy.
BSD 3-Clause "New" or "Revised" License
109 stars 9 forks source link

width is ignored #30

Closed imandr closed 6 years ago

imandr commented 6 years ago

in this fragment width=... is ignored, when used with below()

from histbook import Hist, bin, beside, grid, below
array = numpy.random.normal(0, 1, 1000000)
histogram = Hist(bin("data", 10, -5, 5))
histogram.fill(data=array)
below(histogram.step("data", width=500)).to(canvas) 

without below() it works fine

jpivarski commented 6 years ago

Width is a global property, but the step is not a global element. You need below(h.step(), width=500), but that doesn't exist. One moment...

jpivarski commented 6 years ago

I was wrong: width, height, and title are not global properties (only config is). When you pack N columns of width=300 together, you get a plot of width N*300 + a little bit for margins.

So your syntax is right. I've just passed through the local width, height, and title. The configs get merged in order of plotting, and a global config trumps all.

jpivarski commented 6 years ago

Not sure which point in the conversation your question refers to. I misunderstood at first and had to be corrected.

jpivarski commented 6 years ago

Right now, the way it works is h.step, h.line etc. all have their own width, height, title, and config. The width, height, and title are all local: if you put several of them side-by-side, each has its own width (and the total width is the sum!), own height, and its own title right above the plot.

The only option to set in Combinations like overlay, beside, below, etc. is config. A Vega-Lite JSON document has one master config of global settings. The policy I just put in place is to merge all the configs belonging to the contents of the Conbination, in order from left to right (they can override each other) with the Combination having the last say.

So you can do this:

beside(h.step(width=200), h.area(width=400, config={"background": "blue"})).vegascope()
beside(h.step(width=200), h.area(width=400, config={"background": "blue"}), config={"background": "white"}).vegascope()

The two side-by-side plots have their own widths, which adds up to something a little more than 600 (or maybe exactly 600? I haven't checked). The first line sets a global config from the second inner plot (h.area), which is an awful blue background. In the second line, beside fixes that with its own white background. Conflicting options get resolved from left to right, innermost to outermost. But there's no need to resolve width, height, and title because they're local.