Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
svaberg committed Dec 4, 2019
2 parents 561baa9 + 30922cb commit 2c89f99
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 21 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@
.ipynb_checkpoints/*
.idea
.DS_Store
__pycache__/
__pycache__/
coverage.xml
.coverage
htmlcov
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ install:
- source activate test-environment

script:
- py.test --nbval
- py.test --nbval-lax -v --cov . --cov-report xml
- python-codacy-coverage -r coverage.xml
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# ![The image slurper](img/imageslurper.small.png)

[![Build Status](https://travis-ci.com/svaberg/imageslurper.svg?branch=master)](https://travis-ci.com/svaberg/imageslurper)
[![Codacy Coverage](https://api.codacy.com/project/badge/Coverage/35f5ec8befa64a48b299c8871e004f1e)](https://www.codacy.com/manual/svaberg/imageslurper?utm_source=github.com&utm_medium=referral&utm_content=svaberg/imageslurper&utm_campaign=Badge_Coverage)
[![Codacy Grade](https://api.codacy.com/project/badge/Grade/35f5ec8befa64a48b299c8871e004f1e)](https://www.codacy.com/manual/svaberg/imageslurper?utm_source=github.com&utm_medium=referral&utm_content=svaberg/imageslurper&utm_campaign=Badge_Grade)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/svaberg/imageslurper)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://travis-ci.com/svaberg/imageslurper.svg?branch=master)](https://travis-ci.com/svaberg/imageslurper)

Are you **tired** of asking people for the data behind their published false color plots? Use the image slurper to find the underlying matrix of values from a false-color (heat map) image and its colorbar!

Expand Down
5 changes: 4 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ dependencies:
- matplotlib
- pillow
- jupyter
- nbval
- nbval
- pytest-cov
- codacy-coverage

1 change: 0 additions & 1 deletion imageslurper.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"metadata": {},
"outputs": [],
"source": [
"%reset -f\n",
"%run imageslurper.py\n",
"%run rectangle_picker.py\n",
"%run plot_updater.py"
Expand Down
28 changes: 19 additions & 9 deletions imageslurper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import datetime
import pickle
import time
import logging
log = logging.getLogger(__name__)

from os.path import basename

import IPython.display
Expand All @@ -12,7 +15,7 @@
import numpy as np
from matplotlib.colors import ListedColormap

__version__ = "1.1.0"
__version__ = "1.1.2"


def auto_crop(image, threshold=200, show_steps=False):
Expand Down Expand Up @@ -88,8 +91,12 @@ def auto_scale(nearest_indices, residual_norm, colorbar_data, xlim, ylim, clim):
vmin, vmax = clim[0], clim[1]
scaled_image = nearest_indices / colorbar_length_pixels * (vmax - vmin) + vmin
scaled_error = residual_norm / colorbar_length_pixels * (vmax - vmin)
assert not np.any(np.isnan(scaled_image)), "No NaN values expected in reconstructed image."
assert not np.any(np.isnan(scaled_error)), "No NaN values expected in reconstructed image error."

if np.any(np.isnan(scaled_image)):
log.warning("Found NaN values in reconstructed image.")

if np.any(np.isnan(scaled_error)):
log.warning("Found NaN values in reconstructed image error.")

x = np.linspace(xlim[0], xlim[1], scaled_image.shape[1])
y = np.linspace(ylim[0], ylim[1], scaled_image.shape[0])
Expand All @@ -104,8 +111,8 @@ def auto_hole_fill(data, error, threshold, radius=5):
:param data: image data
:param error: error data
:param threshold: error threshold
:param radius:
:return:
:param radius: radius in which to take median
:return: filled image
"""

data_padded = np.empty([i + 2 * radius for i in data.shape])
Expand Down Expand Up @@ -325,11 +332,12 @@ def autoslurp(file,
colorbar_image = auto_rotate(colorbar_image)

image_data = np.asarray(map_image)

assert not np.any(np.isnan(image_data)), "No NaN values expected in plot area rgb image."
if np.any(np.isnan(image_data)):
log.warning("Found NaN values in plot area rgb image.")

colorbar_image_data = np.asarray(colorbar_image)
assert not np.any(np.isnan(colorbar_image_data)), "No NaN values expected in colorbar rgb image"
if np.any(np.isnan(colorbar_image_data)):
log.warning("Found NaN values in colorbar rgb image")

colorbar_data = np.median(colorbar_image_data, axis=0) # One pixel wide

Expand All @@ -338,7 +346,9 @@ def autoslurp(file,
plt.show()

nearest_indices = buffered_unmap(image_data, colorbar_data, updater=updater, norm_order=1)
assert (nearest_indices.shape[:2] == image_data.shape[:2])
if not nearest_indices.shape[:2] == image_data.shape[:2]:
log.error("Image shapes did not match up (this is likely fatal).")


mapped_colors = colorbar_data[nearest_indices]

Expand Down
2 changes: 1 addition & 1 deletion plot_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def plot_updater(ax=None, cmap=('viridis', 'magma'), update_freq=1):
img = yield

if ax is None:
fig, ax = plt.subplots(figsize=(14, 6))
_, ax = plt.subplots(figsize=(14, 6))

img_img = ax.imshow(img, cmap=cmap[0])
ax.set_xlabel('Pixels')
Expand Down
8 changes: 3 additions & 5 deletions rectangle_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
from matplotlib.patches import Rectangle
from matplotlib.widgets import RectangleSelector

import PIL.Image

# The default rectangles and positions here are chosen to match the default
# The default rectangles and positions here are chosen to match the default
# slurp target used in imageslurper.ipynb.
_boxes = [Rectangle((50, 50), 950, 500, facecolor='green', edgecolor='green', alpha=0.4),
Rectangle((150, 560), 750, 16, facecolor='blue', edgecolor='blue', alpha=0.4)]
Expand All @@ -16,7 +14,7 @@

def line_select_callback(eclick, erelease):
global _user_box_count
'eclick and erelease are the press and release events'
# eclick and erelease are the press and release events
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata

Expand All @@ -34,7 +32,7 @@ def line_select_callback(eclick, erelease):
def select_rectangles(image):
global _rectangle_selector

fig, current_ax = plt.subplots(figsize=(10, 4))
_, current_ax = plt.subplots(figsize=(10, 4))
current_ax.imshow(image)
current_ax.axis('off')

Expand Down
34 changes: 34 additions & 0 deletions test_imageslurper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pytest
import PIL
import numpy as np
import matplotlib.pyplot as plt
import imageslurper

@pytest.mark.parametrize("error_threshold", (None, 20))
def test_autoslurp(error_threshold):
"""
Test of the whole process.
"""
plt.ion()

imageslurper.autoslurp(file="img/world-temp.jpg",
map_corners=np.array([ 50., 50., 1000., 550.]),
colorbar_corners=np.array([150., 560., 900., 576.]),
error_threshold=error_threshold, # In clim units
xlim = (-180, 180),
ylim = (90, -90),
clim = (180, 280),
norm_order=2,
updater=None,
)


@pytest.mark.parametrize("max_pixels", (100, 1e99))
def test_auto_resize(max_pixels):
"""
Test of auto resize as it is not part of the usual slurp.
"""
imageslurper.auto_resize(
PIL.Image.open("img/world-temp.jpg"),
max_pixels=max_pixels,
resample=PIL.Image.NEAREST)

0 comments on commit 2c89f99

Please sign in to comment.