Skip to content

Commit

Permalink
Merge pull request #68 from scikit-hep/henryiii/feat/stack
Browse files Browse the repository at this point in the history
feat: support Stacks from Hist
  • Loading branch information
ast0815 authored Aug 10, 2021
2 parents 78764cd + 2d27160 commit e0af8f8
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 31 deletions.
13 changes: 4 additions & 9 deletions .github/workflows/pythontests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,15 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
python -m pip install -e .[test]
run: python -m pip install -e .[test,boost,root]
- name: Install optional dependencies for tests
run: |
pip install boost-histogram uproot awkward pandas || true
run: pip install pandas
- name: Run tests
run: |
python -m pytest -s tests/test.py
run: python -m pytest -s
- name: Run CLI
run: |
histoprint tests/data/1D.txt
Expand Down
23 changes: 18 additions & 5 deletions histoprint/formatter.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""Module for plotting Numpy-like 1D histograms to the terminal."""

import shutil
from collections.abc import Sequence
from itertools import cycle
from typing import Optional

import click
import numpy as np
from uhi.numpy_plottable import ensure_plottable_histogram
from uhi.typing.plottable import PlottableHistogram

DEFAULT_SYMBOLS = " |=/\\"
COMPOSING_SYMBOLS = "/\\"
Expand Down Expand Up @@ -560,12 +562,23 @@ def get_plottable_protocol_bin_edges(axis):
def get_count_edges(hist):
"""Get bin contents and edges from a compatible histogram."""

# Make sure we have a PlottableProtocol histogram
hist = ensure_plottable_histogram(hist)
# Support sequence of histograms
if isinstance(hist, Sequence) and isinstance(hist[0], PlottableHistogram):
count = np.stack([h.values() for h in hist])
edges = get_plottable_protocol_bin_edges(hist[0].axes[0])
for other_edges in (
get_plottable_protocol_bin_edges(h.axes[0]) for h in hist[1:]
):
np.testing.assert_allclose(edges, other_edges)

else:
# Single histogram or (a,b,c, edges) tuple:
# Make sure we have a PlottableProtocol histogram
hist = ensure_plottable_histogram(hist)

# Use the PlottableProtocol
count = hist.values()
edges = get_plottable_protocol_bin_edges(hist.axes[0])
# Use the PlottableProtocol
count = hist.values()
edges = get_plottable_protocol_bin_edges(hist.axes[0])

return count, edges

Expand Down
35 changes: 35 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

import nox

ALL_PYTHONS = ["3.6", "3.7", "3.8", "3.9"]

nox.options.sessions = ["lint", "tests"]


@nox.session
def lint(session):
"""
Run the linter.
"""
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files", *session.posargs)


@nox.session(python=ALL_PYTHONS, reuse_venv=True)
def tests(session):
"""
Run the unit and regular tests.
"""
session.install(".[test,boost,root]")
session.run("pytest", "-s", *session.posargs)


@nox.session
def build(session):
"""
Build an SDist and wheel.
"""

session.install("build")
session.run("python", "-m", "build")
13 changes: 12 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,23 @@ build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
write_to = "histoprint/version.py"

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra --strict-markers --showlocals --color=yes"
testpaths = [
"tests",
]

[tool.isort]
profile = "black"
multi_line_output = 3

[tool.check-manifest]
ignore=[".pre-commit-config.yaml", "histoprint/version.py"]
ignore = [
".pre-commit-config.yaml",
"histoprint/version.py",
"noxfile.py",
]

[tool.mypy]
files = ["histoprint"]
Expand Down
4 changes: 3 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ console_scripts =
histoprint=histoprint.cli:histoprint

[options.extras_require]
boost =
boost-histogram>=1.1
root =
awkward>=1
uproot>=4
test =
pytest>=4.6
pytest>=6.0

[flake8]
ignore = E203, E231, E501, E722, W503, B950
Expand Down
Empty file removed tests/__init__.py
Empty file.
54 changes: 39 additions & 15 deletions tests/test.py → tests/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import io

import numpy as np
import pytest
from uhi.numpy_plottable import ensure_plottable_histogram

import histoprint as hp

Expand Down Expand Up @@ -59,25 +63,18 @@ def test_nan():
def test_boost():
"""Test boost-histogram if it is available."""

try:
import boost_histogram as bh
except ModuleNotFoundError:
return
bh = pytest.importorskip("boost_histogram")

hist = bh.Histogram(bh.axis.Regular(20, -3, 3))
hist.fill(np.random.randn(1000))
hp.print_hist(hist, title="Boost Histogram")


def test_uproot():
"""Test uproot hsitograms if it is available."""
"""Test uproot histograms if it is available."""

try:
# Only used to check whether modules are available
import awkward # noqa: F401
import uproot
except ModuleNotFoundError:
return
pytest.importorskip("awkward")
uproot = pytest.importorskip("uproot")

with uproot.open("tests/data/histograms.root") as F:
hist = F["one"]
Expand All @@ -90,7 +87,34 @@ def test_uproot():
hp.print_hist(hist, title="uproot TH1")


if __name__ == "__main__":
test_hist()
test_boost()
test_uproot()
def test_stack():
A = np.random.randn(1000) - 2
B = np.random.randn(1000)
C = np.random.randn(1000) + 2
D = np.random.randn(500) * 2

hp.text_hist(B)
hp.text_hist(
B, bins=[-5, -3, -2, -1, -0.5, 0, 0.5, 1, 2, 3, 5], title="Variable bin widths"
)

histA = np.histogram(A, bins=15, range=(-5, 5))
histB = np.histogram(B, bins=15, range=(-5, 5))
histC = np.histogram(C, bins=15, range=(-5, 5))
histD = np.histogram(D, bins=15, range=(-5, 5))
histAll = ([histA[0], histB[0], histC[0], histD[0]], histA[1])

hA = ensure_plottable_histogram(histA)
hB = ensure_plottable_histogram(histB)
hC = ensure_plottable_histogram(histC)
hD = ensure_plottable_histogram(histD)

hist_stack = [hA, hB, hC, hD]

out1 = io.StringIO()
out2 = io.StringIO()

hp.print_hist(histAll, file=out1, title="Overlays", labels="ABCD")
hp.print_hist(hist_stack, file=out2, title="Overlays", labels="ABCD")

assert out1.getvalue() == out2.getvalue()

0 comments on commit e0af8f8

Please sign in to comment.