diff --git a/.gitignore b/.gitignore index dc900fe..f7e7e2f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ NUtil.egg-info/PKG-INFO NUtil.egg-info/requires.txt NUtil.egg-info/SOURCES.txt NUtil.egg-info/top_level.txt +nutil/__pycache__/__init__.cpython-36.pyc +nutil/__pycache__/image.cpython-36.pyc diff --git a/nutil/fake.py b/nutil/fake.py index 842e28c..30502b3 100644 --- a/nutil/fake.py +++ b/nutil/fake.py @@ -9,4 +9,5 @@ def movingSquare(steps=10, shape=(200,200), factor=3): x[i, h+i*factor:2*h+i*factor, w+i*factor:2*w+i*factor] = 1 - return x \ No newline at end of file + return x + diff --git a/nutil/image.py b/nutil/image.py index 8476246..bbf24cb 100644 --- a/nutil/image.py +++ b/nutil/image.py @@ -57,7 +57,11 @@ def browse(x, axis=0, resize=None, enhance_contrast=True, antialiasing=False, cu warning when float arrays are shown """ - s = x.shape + if type(x) == list: + s = (len(x), )+x[0].shape + + else: + s = x.shape assert type(axis) == int, "axis must be an interger" assert len(s) >= 2, "image must be at least 2D" @@ -87,6 +91,7 @@ def browse(x, axis=0, resize=None, enhance_contrast=True, antialiasing=False, cu def __(a:(0, s[axis]-1)): # Dynamic fancy indexing using axis as argument im = np.take(x, a, axis) + already_resized = False # If data should be shown in a specific range if cutoff_min or cutoff_max: @@ -106,12 +111,20 @@ def __(a:(0, s[axis]-1)): # If grayscale image should be colored using a LUT if cmap and len(im.shape) == 2: im = _colorim(im, colors) + + # If image should be smaller, + # and we just can take every nth point, + # do this instead of expensive resizing + if resize is not None: + if 1/resize % 2 == 0: + im = im[::int(1/resize), ::int(1/resize)] + already_resized = True # Convert numpy array to PIL Image im_pil = Image.fromarray(im) # If image is too small and people asked for resizing - if resize is not None: + if resize is not None and not already_resized: w, h = im.shape[:2] im_pil = im_pil.resize((int(h*resize), int(w*resize)), RESIZE_FLAG) diff --git a/nutil/plot.py b/nutil/plot.py new file mode 100644 index 0000000..fd79bbe --- /dev/null +++ b/nutil/plot.py @@ -0,0 +1,43 @@ +import numpy as np +import matplotlib.pyplot as plt +import seaborn as sns + +def paperStyle(use_seaborn=True): + """Defines plot styles for paper + + Args: + use_seaborn (bool, optional): If seaborn is used to style the plot. Defaults to True. + """ + if use_seaborn: + sns.set_style('white') + sns.set_style('ticks') + + plt.rcParams['axes.labelsize'] = 8 + plt.rcParams['xtick.labelsize'] = 8 + plt.rcParams['ytick.labelsize'] = 8 + plt.rcParams['legend.fontsize'] = 8 + plt.rcParams['font.family'] = ['sans-serif'] + plt.rcParams['font.sans-serif'] = ['Arial'] + plt.rcParams['svg.fonttype'] = 'none' # Text is not rendered + plt.rcParams['pdf.fonttype'] = 42 # TrueType to avoid PDF issues + + +def grabFigure(fig, autoclose=True): + """Grabs a figure to a numpy array + + Args: + fig (matplotlib.figure): The figure reference + autoclose (bool, optional): Close the figure automatically. Defaults to True. + + Returns: + np.ndarray, the figure as RGB image numpy array + """ + fig.canvas.draw() + rgb = fig.canvas.tostring_rgb() + shape = fig.canvas.get_width_height()[::-1] + (3,) + + if autoclose: + plt.close(fig) + + # Returns numpy array + return np.frombuffer(rgb, dtype=np.uint8).reshape(shape) \ No newline at end of file