Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ImageViz for mapbox ImageSource #61

Merged
merged 15 commits into from
Mar 16, 2018
Merged

add ImageViz for mapbox ImageSource #61

merged 15 commits into from
Mar 16, 2018

Conversation

vincentsarago
Copy link
Collaborator

This PR tries to add an ImageViz method to enable Mapbox GL static ImageSource.

There is couple things that need to be discussed:

  • do we need to pass data here
    class ImageViz(MapViz):
    """Create a image viz"""
    def __init__(self,
    data,
    image,
    coordinates,
    *args,
    **kwargs):
    """Construct a Mapviz object
  • What kind of image input we want to allow ?
  • I don't know why but image or coordinates needs to be flipped to be displayed correctly on the map

Preview

capture d ecran 2018-03-07 a 11 21 25

cc @dnomadb @ryanbaumann

@vincentsarago vincentsarago self-assigned this Mar 7, 2018
@dnomadb
Copy link

dnomadb commented Mar 7, 2018

I don't know why but image or coordinates needs to be flipped to be displayed correctly on the map

GL JS explicitly takes the order of UL, UR, LR, LL https://www.mapbox.com/mapbox-gl-js/style-spec#sources-image, not W, S, E, N

What kind of image input we want to allow ?

It seems that this would be most useful for displaying manipulated data, which in most cases would be rows, cols, depth numpy ndarrays.

coordinates = [... ]
img = imread('img.jpg')

visualization = ImageViz(img, coordinates, ...)

visualization.show()

Beyond what this might add in terms of ndarray ==> image data encoding within the library, to be more effectively used we'd probably have to add a utility to take data ndarrays and apply a color ramp (which could be done via `matplotlib):

from matplotlib import cm


# data scaled to 0-1
data

# using the viridis colormap
img = (cm.viridis(data) * np.iiinfo(np.uint8).max).astype(np.uint8)

@ryanbaumann
Copy link
Contributor

This is awesome @vincentsarago! Let me know when you're ready for 👀 on a review.

center: {{ center }},
zoom: {{ zoom }},
transformRequest: (url, resourceType)=> {
if ( url.slice(0,22) == 'https://api.mapbox.com' ) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use regex to be more robust in catching requests to the Mapbox api -- older styles may still have

  • api.tiles.mapbox.com
  • a.tiles.mapbox.com
  • b.tiles ..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnomadb good flag. I'll include this change in a separate PR, since it spans all visualization types.

@@ -276,3 +276,33 @@ def add_unique_template_variables(self, options):
clusterRadius=self.clusterRadius,
clusterMaxZoom=self.clusterMaxZoom
))


class ImageViz(MapViz):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vincentsarago could we call this class an ImageLayer? it looks layer-like to me and I think Layer could tell a user a lot about how to use the class.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now it's a proper MapViz, but I think at the end we could make it a layer meaning that instead of having a ImageViz, we could add a addImage function to the MapViz class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, a change to use layer nomenclature makes sense here. I'd propose a renaming of the API from *Viz to *Layer in a separate PR from this one, as a part of #34.

@vincentsarago
Copy link
Collaborator Author

Ok I like the idea of using Matplotlib (+Pillow) if this is what the users are use to do.

Here is what I propose

  • add an utility function to encode the image (ndarray) to a base64 string (plus prefix)
# mapboxgl.utils.img_encode

# `img_encode` is a wrapper arround `matplotlib.image.imsave` 
# https://matplotlib.org/api/image_api.html#matplotlib.image.imsave

import base64
from io import BytesIO

def img_encode(arr, **kwargs):
    """Encode ndarray to base64 string image data

    Parameters
    ----------
    arr: ndarray (rows, cols, depth)
    kwargs: passed directly to matplotlib.image.imsave
    """
    sio = BytesIO()
    imsave(sio, arr, **kwargs)
    sio.seek(0)
    img_format = kwargs['format'] if kwargs.get('format') else 'png'
    img_str = base64.b64encode(sio.getvalue()).decode()
    
    return 'data:image/{};base64,{}'.format(img_format, img_str)
  • document the use of imread to read image file
img = imread('./mosaic.jpg')
img = np.mean(img[::10, ::10], axis=2)
img = img_encode(img, format='png', cmap='gnuplot')

# Coordinates must be an array in the form of [UL, UR, LR, LL]
coordinates = [
    [-123.40515640309, 38.534294809274336],
    [-115.92938988349292, 38.534294809274336],
    [-115.92938988349292, 32.08296982365502], 
    [-123.40515640309, 32.08296982365502]]

# Create the viz from the dataframe
viz = ImageViz(None, img, coordinates, access_token=token,
                height='400px',
                center = (-119, 35),
                zoom = 5)
viz.show()

@dnomadb @ryanbaumann @sgillies

Copy link
Contributor

@ryanbaumann ryanbaumann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vincentsarago looks great! Made a few comments, all optional. Made a small commit to aid running the example locally for the first time.

img_format = kwargs['format'] if kwargs.get('format') else 'png'
img_str = base64.b64encode(sio.getvalue()).decode()

return 'data:image/{};base64,{}'.format(img_format, img_str)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vincentsarago it may be good to include an optional filename output parameter here. This would encourage users to output a local file with the encoded image data so that the mapboxgl viz class can load the image data asynchronously (versus stick it into a large HTML blob).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact I think because mapboxgl can read local files we can totally remove this utility function and show the user it can use imsave

"\n",
" map.addSource('image', {\n",
" 'type': 'image',\n",
" 'url': 'data:image/png;base64,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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vincentsarago let's change this to an async URL load from a local file, if possible, to reduce file size of the notebook and encourage async loading of images.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh well I didn't knew mapboxgl could read a local file 👌

@@ -276,3 +276,33 @@ def add_unique_template_variables(self, options):
clusterRadius=self.clusterRadius,
clusterMaxZoom=self.clusterMaxZoom
))


class ImageViz(MapViz):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, a change to use layer nomenclature makes sense here. I'd propose a renaming of the API from *Viz to *Layer in a separate PR from this one, as a part of #34.

mapboxgl/viz.py Outdated

def __init__(self,
data,
image,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vincentsarago could we simplify the syntax by just passing the pixels or URL for an image to the required data parameter, instead of adding a new parameter?

@ryanbaumann ryanbaumann mentioned this pull request Mar 11, 2018
@@ -14,7 +14,8 @@
"\n",
"```\n",
"pip install mapboxgl\n",
"pip install Pillow numpy\n",
"pip install imread\n",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryanbaumann imread comes from matplotlib which is already installed

install_requires=['jinja2', 'geojson', 'colour', 'matplotlib'],
so no need to install imread

@@ -14,7 +14,8 @@
"\n",
"```\n",
"pip install mapboxgl\n",
"pip install Pillow numpy\n",
"pip install imread\n",
"pip install numpy\n",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, numpy will be installed by default when installing mapboxgl-jupyter

@vincentsarago
Copy link
Collaborator Author

ok going back to @dnomadb point earlier, maybe ImageViz could accept 2 kind of input:

  • path (string), could be url, local path or event base64 encoded image
  • numpy array

If a numpy array is given ImageViz will encode it for the user

cc @ryanbaumann

@vincentsarago
Copy link
Collaborator Author

this is ready @ryanbaumann I'll merge it when the tests will be over !

@vincentsarago vincentsarago merged commit 20ca8fe into master Mar 16, 2018
@vincentsarago vincentsarago deleted the image branch March 16, 2018 16:46
@ryanbaumann
Copy link
Contributor

🎉 @vincentsarago thanks!

@ryanbaumann ryanbaumann mentioned this pull request Mar 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants