Skip to content

Commit

Permalink
Add initial code
Browse files Browse the repository at this point in the history
  • Loading branch information
ibab committed Feb 4, 2016
1 parent 52fbd25 commit b73446a
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 0 deletions.
66 changes: 66 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Sphinx documentation
docs/_build/

# PyBuilder
target/

#Ipython Notebook
.ipynb_checkpoints

# pyenv
.python-version
7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright (c) 2015 Igor Babuschkin

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# matplotlib-hep

An add-on for matplotlib that simplifies the creation of plots for high energy physics.

## The histpoints plotting function

In high energy physics, histograms are often displayed as a collection of data points, one for each bin.
This allows one to easily compare the data to an underlying probability model.

It can be debated if it is correct to attach error bars to the individual bin contents as opposed to the underlying model,
as we want to know if our expectation for any given bin could fluctuate to match the data and not vice versa.
But this is a convention widely used by the HEP community, and thus a way to use this kind of plot in Python is often necessary.

A simple way to create these kinds of plots is missing from other Python packages like matplotlib.
The `histpoints` function is designed to produce these plots conventiently, like in the following example:

```python
from missing_hep import histpoints
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats

data = np.random.normal(0, 1, 200)
x, y, norm = histpoints(data)

xs = np.linspace(-4, 4, 200)
plt.plot(xs, norm * stats.norm.pdf(xs, 0, 1), 'b-', lw=2)

plt.savefig('histpoints.png')
```

![histpoints](./histpoints.png)

Or, displaying horizontal error bars to mark the bin width:
```python
histpoints(data, xerr='binwidth')
```

![histpoints\_binwidth](./histpoints_binwidth.png)

By default, the number of bins is chosen automatically via the Freedman-Diaconis rule.

Binary file added histpoints.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added histpoints_binwidth.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions matplotlib_hep/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from __future__ import division

import numpy as np
import scipy.stats as stats
import scipy as sp
import logging

__all__ = ['histpoints', 'calc_nbins']

def calc_nbins(x, maximum=150):
n = (max(x) - min(x)) / (2 * len(x)**(-1/3) * (np.percentile(x, 75) - np.percentile(x, 25)))
return min(n, maximum)

def poisson_limits(N, kind, confidence=0.6827):
alpha = 1 - confidence
upper = np.zeros(len(N))
lower = np.zeros(len(N))
if kind == 'gamma':
lower = stats.gamma.ppf(alpha / 2, N)
upper = stats.gamma.ppf(1 - alpha / 2, N + 1)
elif kind == 'sqrt':
lower = sqrt(N)
upper = lower
else:
raise ValueError('Unknown errorbar kind: {}'.format(kind))
# clip lower bars
lower[N==0] = 0
return N - lower, upper - N

def histpoints(x, bins=None, xerr=None, yerr='gamma', normed=False, **kwargs):
"""
Plot a histogram as a series of data points.
Compute and draw the histogram of *x* using individual (x,y) points
for the bin contents.
By default, vertical poisson error bars are calculated using the
gamma distribution.
Horizontal error bars are omitted by default.
These can be enable using the *xerr* argument.
Use ``xerr='binwidth'`` to draw horizontal error bars that indicate
the width of each histogram bin.
Paramters
---------
x : (n,) array or sequence of (n,) arrays
Input values. This takes either a single array or a sequency of
arrays which are not required to be of the same length
"""
import matplotlib.pyplot as plt

if bins is None:
bins = calc_nbins(x)

h, bins = np.histogram(x, bins=bins)
width = bins[1] - bins[0]
center = (bins[:-1] + bins[1:]) / 2
area = sum(h * width)

if isinstance(yerr, str):
yerr = poisson_limits(h, yerr)

if xerr == 'binwidth':
xerr = width / 2

if normed:
h = h / area
yerr = yerr / area
area = 1.

if not 'color' in kwargs:
kwargs['color'] = 'black'

if not 'fmt' in kwargs:
kwargs['fmt'] = 'o'

plt.errorbar(center, h, xerr=xerr, yerr=yerr, **kwargs)

return center, h, area

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
matplotlib
11 changes: 11 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from setuptools import setup

setup(name='matplotlib-hep',
version='0.1.0',
description='Module for making data analysis in High Energy Physics with Python more convenient',
url='http://github.com/ibab/matplotlib-hep',
author='Igor Babuschkin',
author_email='igor@babuschk.in',
license='MIT',
packages=['matplotlib_hep'],
zip_safe=False)

0 comments on commit b73446a

Please sign in to comment.