Coder Social home page Coder Social logo

sarthakjariwala / seaborn-image Goto Github PK

View Code? Open in Web Editor NEW
67.0 4.0 7.0 37.15 MB

High-level API for attractive and descriptive image visualization in Python

Home Page: https://seaborn-image.readthedocs.io/

License: MIT License

Python 100.00%
image-processing matplotlib scikit-image scipy visualization image-visualization visualization-library python seaborn-image

seaborn-image's Introduction

seaborn-image: image data visualization

Tests Codecov PyPI Documentation Status Code style: black

Description

Seaborn-image is a Python image visualization library based on matplotlib and provides a high-level API to draw attractive and informative images quickly and effectively.

It is heavily inspired by seaborn, a high-level visualization library for drawing attractive statistical graphics in Python.

Documentation

Detailed documentation can be found here.

Installation

For latest release:

Using pip

pip install -U seaborn-image

Using conda

conda install seaborn-image -c conda-forge

For latest commit

pip install git+https://github.com/SarthakJariwala/seaborn-image

Contributing

Please see the contributing guidelines

seaborn-image's People

Contributors

cinnamonjui avatar dependabot-preview[bot] avatar dependabot[bot] avatar eugeniolr avatar sarthakjariwala avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

seaborn-image's Issues

Allow `filterplot` to take in any arbitrary scipy/skimage filter

Current implementation :

>>> import seaborn_image as isns

>>> isns.filterplot(data, "gaussian", sigma=10)

Only allows filters implemented (wrapped) in seabron-image

Allow the following too :

>>> import seaborn_image as isns
>>> import scipy.ndimage as ndi

>>> isns.filterplot(data, ndi.gaussian_filter, sigma=10)

This way if a specific filter isn't implemented in seaborn-image; users can still use their chosen filter.

Add `gray` parameter to convert RGB to grayscale and plot grayscale images

Implementation

# If data is a RGB image and gray is True, 
# convert to rgb to grayscale internally and plot image using a grayscle colormap
>>> isns.imgplot(data, gray=True)

# If data has only 2 dimensions and gray is True, plot image using grayscale colormap
>>> isns.imgplot(data, gray=True)

# If gray is True and cmap is not None, use cmap instead of grayscale colormap
# If data is RGB, conversion to grayscale will still be performed
>>> isns.imgplot(data, gray=True, cmap="deep")

Add a function like rgbplot for other color formats and generic data

I think it would be a good idea to make a function like rgbplot, showing the channels of each image separately, but not assuming it's an image in RGB, it could be an image in other color formats or even generic data (as could be the case in a deep learning problem) where there could be any number of channels to an image.

It could also be a good idea to make something like ImageGrid, but where each row is a different image and each column is a different channel of the image, but i'm not so sure about this because you can manually do it with existing functions.

I've made some code in this respect already, so if it this seems like a good idea i can make a pull request when we have discussed all the necesary details.

Deprecate `FilterGrid` : Rename to `ParamGrid`

The functionality currently in FilterGrid is the following - Given some image data and a function, FilterGrid allows for visualization of effect of different parameters on the image. There is no 'restriction' for the function involved to be an 'image filter' - It could be any function....So the more accuarate name would be something like :

ParamGrid : Explore the interplay between one or more parameters of a given function on input image data.

The functionality of FilterGrid would not change but only renamed to ParamGrid and the usage of FilterGrid would issue a deprecation warning.

Wrong behavior when integrating with a Qt app (PySide2)

Hi!

We are trying to integrate seaborn-image into an app developed at our lab, the app is written in Python+Qt, using PySide2. To be specific the app contains a QMDIArea, where several subwindows can appear, one of them is supposed to be a Matplotlib figure. With Matplotlib this works just fine, however when using isbn.imgplot inside the subclassed matplotlib figure this happens:

image

Another image window is opened. The main reason this occours is in seaborn_image._core:

    def _setup_figure(self):
        """Wrapper to setup image with the desired parameters"""
        if self.ax is None:
            f, ax = plt.subplots()
        else:
            f = plt.gcf()
            ax = self.ax

When providing a matplotlib axes object, I think should use the axes itself to determine the figure rather than pyplot. So, I would say this has to be something like:

   def _setup_figure(self):
       """Wrapper to setup image with the desired parameters"""
       if self.ax is None:
           f, ax = plt.subplots()
       else:
           f = self.ax.get_figure() or plt.gcf()
           ax = self.ax

I might oversighted something and there is a way to deal with this situation in the seaborn-image API, if that is the case, sorry for the inconvenience.

Cheers,

Ismael

"Chain" filters in `filterplot` (?)

Allow chaining different filters together to give a final filtered image

For example, Raw Image ---> Gaussian Filter ---> Percentile Filter ---> Visualize the final filtered image

Currently, in filterplot() only individual filters are supported.

Potential challenges

While the filters that need to be applied can be passed as a list or something, the kwargs for the different filters need to be handled correctly. Can't just dump all the kwargs into the individual functions...

Something that could work (?)

Create a new chain_kw or something and have the individual filter parameters be supplied in there.
Maybe something like this (?) :

isns.filterplot(img, ["gaussian", "percentile"], chain_kw=[{"sigma" : 2}, {"percentile" : 10, "size" : 10}] )

Can't input colormaps to imshow

Hi, i was trying to use a colormap from the sunpy library to display images of the sun with seaborn_image, but i encountered a bug where when reading the Colormap class it throws an "unhashable type" error.

Here's a piece of code to reproduce the bug:

import numpy as np
import matplotlib.cm as cm
import seaborn_image as isns

img = np.random.random([32,32])
isns.imshow(img, cmap=cm.get_cmap("inferno"))

This yeilds the following error:

TypeError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 isns.imshow(img, cmap=cm.get_cmap("inferno"))

File [~/.local/lib/python3.10/site-packages/seaborn_image/_general.py:362](https://file+.vscode-resource.vscode-cdn.net/home/eugeniolr/Documents/invAI/misc/~/.local/lib/python3.10/site-packages/seaborn_image/_general.py:362), in imshow(data, **kwargs)
    359 @is_documented_by(imgplot)
    360 def imshow(data, **kwargs):
--> 362     ax = imgplot(data, **kwargs)
    364     return ax

File [~/.local/lib/python3.10/site-packages/seaborn_image/_general.py:345](https://file+.vscode-resource.vscode-cdn.net/home/eugeniolr/Documents/invAI/misc/~/.local/lib/python3.10/site-packages/seaborn_image/_general.py:345), in imgplot(data, ax, cmap, gray, vmin, vmax, alpha, origin, interpolation, norm, robust, perc, dx, units, dimension, describe, map_func, cbar, orientation, cbar_log, cbar_label, cbar_ticks, showticks, despine, **kwargs)
    320     data = map_func(data, **map_func_kwargs)
    322 img_plotter = _SetupImage(
    323     data=data,
    324     ax=ax,
   (...)
    342     despine=despine,
    343 )
--> 345 f, ax, cax = img_plotter.plot()
    347 if describe:
    348     result = ss.describe(data.flatten())

File [~/.local/lib/python3.10/site-packages/seaborn_image/_core.py:105](https://file+.vscode-resource.vscode-cdn.net/home/eugeniolr/Documents/invAI/misc/~/.local/lib/python3.10/site-packages/seaborn_image/_core.py:105), in _SetupImage.plot(self)
    102 def plot(self):
    103     f, ax = self._setup_figure()
--> 105     if self.cmap in _CMAP_QUAL.keys():
    106         self.cmap = _CMAP_QUAL.get(self.cmap).mpl_colormap
    108     if self.robust:

TypeError: unhashable type: 'ListedColormap'

cm.get_cmap("inferno") returns a colormap of type 'ListedColormap', if this code is executed but using matplotlib's imshow function everything works fine.

Interplay between aspect ratio and imghist

I am not quite sure how the aspect parameter is interacting with the size of the histogram in the imghist function. For a square image, with the vertical orientation, an aspect ratio of 1.0 produces a histogram taller than the image. For a square image, with the vertical orientation, the default aspect ratio (1.75) appears to produce a histogram that is the same height as the image. What is the logic here?

OSError in `load_image` when called from outside repository folder

Although load_image() is designed specifically for making documentation easier, it would be good to have it working outside of that scope. If it is called from outside the repository folder, it throws OSError because of the hardcoded paths to the data. Only, load_image("cells") works outside the repo scope because it uses pooch` to retrieve the "cells" data hosted on skimage tutorials.

Find an alternative to hardcoded paths or just retrieve from GitHub repo using pooch...

Newer versions of python are (probably) not supported.

I wanted to use this library with some modern code using python 3.11 but i can't get it to work.

When installing via pip in a PC with ArchLinux with python 3.11.5 installed it gives a strange error like the one bellow.
image

I assume this is an issue with this package, but i don't really know.

Blend two image into 1 image

Hi,

I want to blend two images into one image like in matplotlib. Is it possible? Because when I tried this code, it plotted two images

`isns.set_image(cmap="magma", origin="upper",despine=True)

    isns.imgplot(im.resize((w, h), Image.ANTIALIAS),alpha=0.5)

    isns.imgplot(dec_attn_weights[0, idx].view(h, w))

    plt.show()`

Capture

Using map_func on ImageGrid with a list of images modifies the original list

If you provide a list of images to ImageGrid and function in the map_func attribute the function is applied to the original images and they are permanently changed.

Here is some example code to recreate the issue, first we create 2 random images and we visualize them

img1 = np.random.random((32,32))
img2 = np.random.random((32,32))

image_list = [img1, img2]
isns.ImageGrid(image_list)

output

Then we use ImageGrid with a function that sets some of the values to 0, notice that the original array is never modified since it is copied before the prodecure

def apply_to_imgs(img):
    replacement = img.copy()
    replacement[5:, :-5] = 0
    return replacement

isns.ImageGrid(image_list, map_func = apply_to_imgs)

output2

This is all expected behaviour.

Now if we show the original list again without applying the function, the original images have been modified

isns.ImageGrid(image_list)

output3

This is most likely a bug caused by modifying directly the list passed as an input.

Add support for robust plotting of RGB images

Firstly, thanks for this wonderful library. If it had been around during my PhD it would have saved me a lot of time!

My PhD was in satellite imaging, and I still work in that area today. When visualising satellite images, we often want to apply a robust image stretch (eg. a 2%-98% percentile stretch) to an RGB image. The way this works is by doing a stretch on each band separately, and then combining them together.

This doesn't seem to be possible with seaborn_image at the moment: I notice that in

robust = False # set robust to False if RGB image
, robust is set to False if it's a RGB image.

I've had a bit of a poke around in the code, and it seems like the robust image display is done using vmax and vmin parameters to matplotlib. It looks like those probably don't support doing a different stretch on each band - so it would probably have to be done manually, making it a bit more difficult.

Anyway, I might have time to play around with this sometime (depending on work constraints) - would this be something you'd be interested in? It might require a change to how the library deals with robust plotting.

Update pyproject.toml to require matplotlib-scalebar > 0.7.0

The Matplotlib rcParams Dict doesn't get updated to include scalebar.width_fraction until Release v.0.7.0 of matplotlib-scalebar.

i.e. version check in ./pyproject.toml should probably change from:
matplotlib-scalebar = ">=0.6.2,<0.8.0"
to
matplotlib-scalebar = ">=0.7.0,<0.8.0"

Update to use matplotlib 3.6

Matplotlib has some pending deprecations and behavior change while re-registering a cmap: prior to 3.5 it raised a warning whereas in 3.6 it raises ValueError (if force=False)

This part of a multi-stage refactor - see here for more

PR where it was found: #480 (comment)

[Security] Workflow release-drafter.yml is using vulnerable action release-drafter/release-drafter

The workflow release-drafter.yml is referencing action release-drafter/release-drafter using references v5.13.0. However this reference is missing the commit 70eb821099dbcd875c2cba75dad4332d3cf5544d which may contain fix to the some vulnerability.
The vulnerability fix that is missing by actions version could be related to:
(1) CVE fix
(2) upgrade of vulnerable dependency
(3) fix to secret leak and others.
Please consider to update the reference to the action.

Matplotlib depreciation error on library loading

Unable to load seaborn-image after installing on a fresh python install (via pip, works fine if installed via conda). Error below.

>>> import seaborn_image as isns
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/opt/homebrew/Caskroom/mambaforge/base/lib/python3.10/site-packages/seaborn_image/__init__.py", line 7, in <module> from ._general import * File "/opt/homebrew/Caskroom/mambaforge/base/lib/python3.10/site-packages/seaborn_image/_general.py", line 11, in <module> from ._core import _SetupImage File "/opt/homebrew/Caskroom/mambaforge/base/lib/python3.10/site-packages/seaborn_image/_core.py", line 5, in <module> from matplotlib_scalebar.scalebar import ScaleBar File "/opt/homebrew/Caskroom/mambaforge/base/lib/python3.10/site-packages/matplotlib_scalebar/scalebar.py", line 115, in <module> matplotlib.rcParams.validate = dict( File "/opt/homebrew/Caskroom/mambaforge/base/lib/python3.10/site-packages/matplotlib_scalebar/scalebar.py", line 118, in <genexpr> if key not in matplotlib._all_deprecated File "/opt/homebrew/Caskroom/mambaforge/base/lib/python3.10/site-packages/matplotlib/_api/__init__.py", line 224, in __getattr__ raise AttributeError( AttributeError: module 'matplotlib' has no attribute '_all_deprecated'

Get and print image statistics

Add a describe parameter to print image statistics if set to True

Possible implementation:

>>> isns.imgplot(data, describe=True) 
>>> isns.imghist(data) # auto set it to True for imghist function

Add option in ImageGrid to automatically detect the aspect ratio to use

I have been using ImageGrid to plot images with shapes like 20x40 and i noticed there was a lot of white space between them. I thought this was a bug and i was just about to report it, but i noticed that there is a parameter called aspect that can be set to be the same as the inputted images which solves the issue.

I think it would be a good idea to have this parameter be adjusted automatically instead of being 1 by default. Probably setting it to 'auto' and calculating it as the minimum of the ratio between length and width of all the images.

If this sounds good I can get to it and make a pull request.

Add `overlay` parameter to `ImageGrid`

Add ability to overlay multiple images in ImageGrid using a new overlay parameter.

g = isns.ImageGrid(IMG_LIST, overlay=True)
g = isns.ImageGrid(3D_IMG, overlay=True)
```
would result in a `ImageGrid` object with a single axes with overlayed images.

This would then also allow users to supply different colormaps for the overlay - 

```python
g = isns.ImageGrid(IMG_LIST, overlay=True, cmap=["Reds", "Blues", "Greens"])

scikit-image requirements on conda-forge

Import error for seaborn-image because difference_of_gaussians not available in the version of scikit-image I have installed. The requirement is for scikit-image >= 0.17. Can this be added to the dependencies on conda-forge so that conda updates dependencies when required.

imghist docstring is off

The docstring for imghist lists a different set of arguments than what the function accepts:

def imghist(
    data,
    cmap=None,
    bins=None,
    vmin=None,
    vmax=None,
    alpha=None,
    origin=None,
    interpolation=None,
    norm=None,
    robust=False,
    perc=(2, 98),
    dx=None,
    units=None,
    dimension=None,
    describe=False,
    map_func=None,
    cbar=True,
    orientation="v",
    cbar_log=False,
    cbar_label=None,
    cbar_ticks=None,
    showticks=False,
    despine=None,
    height=5,
    aspect=1.75,
    **kwargs,
):
    """Plot data as a 2-D image with histogram showing the distribution of
    the data. Options to add scalebar, colorbar, title.
    Parameters
    ----------
    data : array-like
        Image data. Supported array shapes are all `matplotlib.pyplot.imshow` array shapes
    bins : int, optional
        Histogram bins, by default None. If None, `auto` is used.
    ax : `matplotlib.axes.Axes`, optional
        Matplotlib axes to plot image on. If None, figure and axes are auto-generated, by default None
    cmap : str or `matplotlib.colors.Colormap`, optional
        Colormap for image. Can be a seaborn-image colormap or default matplotlib colormaps or
        any other colormap converted to a matplotlib colormap, by default None
    gray : bool, optional
        If True and data is RGB image, it will be converted to grayscale.
        If True and cmap is None, cmap will be set to "gray", by default None
    vmin : float, optional
        Minimum data value that colormap covers, by default None
    vmax : float, optional
        Maximum data value that colormap covers, by default None
    alpha : float or array-like, optional
        `matplotlib.pyplot.imshow` alpha blending value from 0 (transparent) to 1 (opaque),
        by default None
    origin : str, optional
        Image origin, by default None
    interpolation : str, optional
        `matplotlib.pyplot.imshow` interpolation method used, by default None
    norm : `matplotlib.colors.Normalize`, optional
        `matplotlib` Normalize instance used to scale scalar data before
        mapping to colors using cmap
    robust : bool, optional
        If True and vmin or vmax are None, colormap range is calculated
        based on the percentiles defined in `perc` parameter, by default False
    perc : tuple or list, optional
        If `robust` is True, colormap range is calculated based
        on the percentiles specified instead of the extremes, by default (2, 98) -
        2nd and 98th percentiles for min and max values
    dx : float, optional
        Size per pixel of the image data. Specifying `dx` and `units` adds a scalebar
        to the image, by default None
    units : str, optional
        Units of `dx`, by default None
    dimension : str, optional
        dimension of `dx` and `units`, by default None
        Options include (similar to `matplotlib_scalebar`):
            - "si" : scale bar showing km, m, cm, etc.
            - "imperial" : scale bar showing in, ft, yd, mi, etc.
            - "si-reciprocal" : scale bar showing 1/m, 1/cm, etc.
            - "angle" : scale bar showing °, ʹ (minute of arc) or ʹʹ (second of arc)
            - "pixel" : scale bar showing px, kpx, Mpx, etc.
    describe : bool, optional
        Brief statistical description of the data, by default False
    map_func : callable, optional
        Transform input image data using this function. All function arguments must be passed as kwargs.
    cbar : bool, optional
        Specify if a colorbar is to be added to the image, by default True.
        If `data` is RGB image, cbar is False
    orientation : str, optional
        Specify the orientaion of colorbar, by default "v".
        Options include :
            - 'h' or 'horizontal' for a horizontal colorbar to the bottom of the image.
            - 'v' or 'vertical' for a vertical colorbar to the right of the image.
    cbar_log : bool, optional
        Log scale colormap and colorbar
    cbar_label : str, optional
        Colorbar label, by default None
    cbar_ticks : list, optional
        List of colorbar ticks, by default None
    showticks : bool, optional
        Show image x-y axis ticks, by default False
    despine : bool, optional
        Remove axes spines from image axes as well as colorbar axes, by default None
    height : int or float, optional
        Size of the individual images, by default 5.
    aspect : int or float, optional
        Aspect ratio of individual images, by default 1.75.

I can't propose a fix now, but creating this ticket so that at least it's tracked.

New feature for symmetic colormaps on images with negative values

I have been using this library a lot and one small inconvenience i find all the time is when i want to visualize images with positive and negative values, where i use a color map like "seismic" expecting to find positive values in red and negative values in blue, but the range of values detected don't align.

To put a practical example, here i'm trying to visualize a covariance matrix.

Using the imgplot indicating only the color map i get the following image:
isns.imgplot(cov, cmap="seismic")
image

To fix this, i have to specify the range of values i want to show

vmin = -np.abs(cov).max()
vmax = np.abs(cov).max()
isns.imgplot(cov, cmap="seismic", vmin=vmin, vmax=vmax)

image

It's not that much of an issue, but it gets a bit more cumbersome when I'm showing a grid of images.

It could be a good idea to add a flag to imgplot and other functions to handle this type of images.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.