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 image overlay #152

Merged

Conversation

andrewgiessel
Copy link
Contributor

This PR addresses #149.

As of submission, it is not complete. I think I am adding layers correctly and put in the right template form, but it is not adding the layer to the rendered map.

@ocefpaf What am I missing?

@@ -16,6 +16,8 @@
import json
from uuid import uuid4

import imageio
Copy link
Member

Choose a reason for hiding this comment

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

I think its best to import this inside def image_overlay() to keep this an "optional" dependency (same way we deal with pandas.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good - the reason the travis builds fail is because of this dependancy.

Copy link
Member

Choose a reason for hiding this comment

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

There will be (probably) other failures that are unrelated. That is something I have on my plate to fix. Ignore them for now...

BTW add imageio to our .travis.yml!

@ocefpaf
Copy link
Member

ocefpaf commented Jul 17, 2015

@andrewgiessel nice work! I made a few inline comments. As a first pass we need:

  1. Docstrings
  2. A test
  3. Update the CHANGE.TXT file

@andrewgiessel
Copy link
Contributor Author

Great! I agree with all of your comments, especially the min_ / max_ arguments- they are much more clear. I'll make those changes, and the 4 other things: docs, test, change.txt and travis.xml.

When I run this locally, the generated HTML file doesn't have the have anything in the overlay layer. I'll look into it, but is there something we need add when the map is rendered to include the overlaid images?

Edit: is master still 0.1.5? Should I add this to that section in CHANGES.txt?

@andrewgiessel
Copy link
Contributor Author

also- is there a typo here? Shouldn't we add data_layers not data_string?

@andrewgiessel
Copy link
Contributor Author

Ok, update. I realized the thing I needed to do was to edit the main html template! Derp. Then, I thought I needed the overlay with the other layers (which can work, but isn't needed and was hard to get it to turn on by default). So, I looked again at what you did in the html and realized it needed to go after the map creation call, and now it works.

TODO still: docstring, test, changes, maybe readme.md (!).

I did a small refactor of the data_layer string/template, but it doesn't seem to do anything and always seems empty. I can revert that edit if you want, but if you could look at add_tile_layer() I think that would be a good thing.

The only major outstanding thing is the bug when you have a bit image and zoom a lot. I'm sure you'll see what I mean when you try it. It might not be worth fixing, and instead let upstream (leaflet) fix it.

@andrewgiessel
Copy link
Contributor Author

image

@ocefpaf
Copy link
Member

ocefpaf commented Jul 19, 2015

This is looking good! Thanks @andrewgiessel!!

I am having some connection issues this, week so I cannot review this until next Friday.

@themiurgo
Copy link
Contributor

Yes, this looks great @andrewgiessel ! 👍

@andrewgiessel
Copy link
Contributor Author

Thanks @ocefpaf + @themiurgo ! I am really happy with it too. The one thing I wanted to do was look into going from NxM to NxMx3 using a MPL colormap. might roll my own simple external lib.

No problem re timing @ocefpaf. I'll hopefully have everything 'merge-ready' by then.

@andrewgiessel
Copy link
Contributor Author

Ah, just a little research into MPL means that this is already taken care of, and that we don't need to support anything fancy, because it's out of scope. 'image_overlay' will take a png, and that can be an NxM, NxMx3, NxMx4.

For reference:

import matplotlib.cm as cm
import numpy as np

converter = cm.ColorMapper('jet')
imageio.imwriter('test.png', converter.to_rgba(np.random.random((100,100)))

@themiurgo
Copy link
Contributor

That's great! It would be great to integrate this into the docs, as it might be out of reach to those not familiar with matplotlib.

Would you mind writing a few lines in the docs? If not that's totally cool and we'll take care of it some other time. Thanks again!

@andrewgiessel
Copy link
Contributor Author

@themiurgo you bet, writing the docstrings now.

This is going to be a nice feature that is intermediate to a full blown WMS server. We should update README to highlight an example.

@andrewgiessel
Copy link
Contributor Author

Docstring updated. What version should this go under in CHANGES.txt?

@andrewgiessel
Copy link
Contributor Author

Ok, added a passing test! I think that the only thing left is to add something to CHANGES.TXT and perhaps readme.rst. The README looks like it could use a general refresh and so this might be very close indeed.

@andrewgiessel
Copy link
Contributor Author

Oddly, the test fails in travis, but not locally. Looking into it now.

@andrewgiessel
Copy link
Contributor Author

Ok, the travis build succeeds on the new test. The error is in fit_bounds - the dictionary is not ordered and thus the rendering happens in a random way. It passes on 2.7 and 3.4 but not on 3.3.

Output:

map.fitBounds([[52.193636, -2.221575], [52.636878, -1.139759]],
    {"padding": [3, 3], "maxZoom": 15}
);
map.fitBounds([[52.193636, -2.221575], [52.636878, -1.139759]],
    {"padding": [3, 3], "maxZoom": 15}
);

Edit: this example is the working one. It fails when the order is off, obviously.

@andrewgiessel
Copy link
Contributor Author

One thought I had: does image_overlay to projection to web mercator, or spherical or whatever the basemap is in?

@BibMartin
Copy link
Contributor

hi @andrewgiessel ; that looks like great work !

I'm sorry for being late in the discussion.

A few thoughts :

  • Maybe this kind of enhancement could be added as plugins (see Plugins object and a few plugins #151) so that it does not complexify folium.py and fol_template.html.
  • In Leaflet, you can use imageOverlay with either a url or a base64 string (like L.imageOverlay("data:image;base64,iVBORw0K....5ErkJggg==", ...);). This would be interesting to enable such embedings for those who wants a fully autonomous html (useful for example if you want to embed your folium map inside of an iframe in a notebook.)
  • Based on http://stackoverflow.com/questions/902761/saving-a-numpy-array-as-an-image, it may be possible to avoid the dependency to imageio (there's an answers defining a function saveAsPNG using only the standard library). But I wonder whether it would not be simpler to ask for an image file/object and let the user convert his array to an image outside of folium...?

Again I'm late and sorry for this ; maybe I'll do another PR after your merge to integrate this. But I'd be interested in having your feeling about it.

@andrewgiessel
Copy link
Contributor Author

@BibMartin Thanks!

  • I have to admit I'm not 100% clear re: plugins in folium, although modularity is obviously good. I'd be happy to refactor but it seems like you are on a roll there- maybe after this?
  • PNG as a base64 string is a fantastic idea as is removing the imageio dependency (although I am frankly very impressed with imageio). As stated above, referencing external styles is tricky if there is a mis-match between the current path (in the python kernel) and the current URL path.

edit: i can look into this as the final commits of the PR, or we can add it as a feature after.

@andrewgiessel
Copy link
Contributor Author

As as aside, I mashed around enough last wee to get some tiles rendered to disk using gdal2tile.py. It was not an easy requirement stack to sort out and the tiles really took a long time to generate. However, the multi-res zoom was obviously awesome and the projections seemed correct.

I think this PR is a good quick and dirty solution, however, I would like feedback about how bad any projection artifacts might be.

Also, any domain experts want to break down the options for tile servers? =)

@andrewgiessel
Copy link
Contributor Author

@ocefpaf @BibMartin @themiurgo

Aside from the optional feature of doing embedded PNGs, the only thing I think that remains is the CHANGES.txt file. Let me know what I need to do to move forward! Thanks!

@ocefpaf
Copy link
Member

ocefpaf commented Jul 27, 2015

@andrewgiessel:

One thought I had: does image_overlay to projection to web mercator, or spherical or whatever the basemap is in?

I believe leaflet is always "web mercator". Unless...

The error is in fit_bounds.

Yep. I have had a fix sitting here, but you beat me to it 😜

  • Go ahead with the CHANGES.txt
  • Squash the commits
  • And...

I like imageio and "clean" HTMLs (no base64 noise) . But, but, but... practicality beats purity. So one less dependency+stand alone HTMLs is better.

Can you implement @BibMartin suggestions (2 and 3). If not please open issues for 2 and 3, so we do not lose track.

As as aside, I mashed around enough last wee to get some tiles rendered to disk using gdal2tile.py

  • Awesome! But lets think about this in another PR. We have use for simple overlays and tiles.

@BibMartin:

  • Regarding your suggestion 1: I would love to see this implemented as plugins. But lets do that later and get @andrewgiessel contribution as is. (Can either one of you open an issue to remind us?)

Thanks @themiurgo for the review!
Thanks @BibMartin for the important suggestions!
And thanks @andrewgiessel for the PR!

🎉 Hurray community!!! 🎉

@BibMartin
Copy link
Contributor

@andrewgiessel

I'd be happy to refactor but it seems like you are on a roll there- maybe after this?

I agree ; let's finish up on both sides.

@ocefpaf

I like imageio and "clean" HTMLs (no base64 noise) . But, but, but... practicality beats purity. So one less dependency+stand alone HTMLs is better.

imageio and base64 are complementary to me. One shall have the choice between using imageio or providing a png generated elsewhere. And one shall have the choice between linking to a png on the disk or embeding it with base64.
But again, I imagine this can be done later ; there's already quite a lot of awesome work in this PR.

@andrewgiessel
Copy link
Contributor Author

I wanted to share this gist here. It takes a numpy array, converts it to a byte array (which is really a string), then both encodes as a PNG. That buffer can be directly saved to disk or encoded in base64 for direct embedding in HTML

https://gist.github.com/andrewgiessel/d5e1a11604af4aee5962

I'm about to use this to do the changes we talked about above, and then fix the build errors I caused by merging in upstream. At that point we should be good to merge.

I'll make issues for any outstanding stuff, too.

@themiurgo
Copy link
Contributor

Great, thanks a lot! 😄 Once done with all the outstanding issues, please squash all the commits. If you're unsure about how to do it, please let us know and we'll guide you.

@andrewgiessel
Copy link
Contributor Author

I generally don't squash commits so if you have a URL that'd be handy, otherwise I'll google a bit.

@themiurgo
Copy link
Contributor

http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html

tl;dr Identify the HEAD of the first, commit and then run git rebase -i HASH. Write pick in the first commit line, squash in all other commit lines.

@ocefpaf
Copy link
Member

ocefpaf commented Jul 29, 2015

@andrewgiessel one important thing to note is that you won't be able to push after the squash. You'll have to push -f (force push). That is OK in branches.

@andrewgiessel
Copy link
Contributor Author

DING. green! I am going to do some manual tests and then try and squash.

@andrewgiessel
Copy link
Contributor Author

@themiurgo sorry for the ignorance, but how do i find the HEAD of the first commit? I tried to use the hash of the first commit of the PR, but I think that is one too late (the pick/squash options started after that)

do i need to look in the output of git log?

Just don't want to lose work here... and trying to get better at git =)

EDIT: i think i found it.

@BibMartin
Copy link
Contributor

You can use git log, but you can also wtch there : https://github.com/andrewgiessel/folium/commits/add-image-overlay

@andrewgiessel
Copy link
Contributor Author

I think I did it? pinging @ocefpaf @themiurgo

I only have one commit but the message is really long, I'm not sure what happened, I tried to keep only the first one (Add image_overlay()) edit: fixed

@themiurgo
Copy link
Contributor

@andrewgiessel you did it! it would be great if you could change the commit message (shorten it to one line), to something that explains what the commit / PR is about. You can change the commit message by performing again a rebase (git rebase -i) and use the command reword.

@ocefpaf
Copy link
Member

ocefpaf commented Jul 30, 2015

Shoot!!

@andrewgiessel Now you need to rebase against master (not your fault, we just merged some stuff). If you want to keep your git-fu road to mastery I can give you some pointer. Otherwise I can do that for you in a PR to your branch.

@andrewgiessel
Copy link
Contributor Author

@themiurgo I shortened it using git commit --amend and a git push -f

@ocefpaf I'll try a rebase on master now...

@themiurgo
Copy link
Contributor

I checked out locally your branch, just in case something goes wrong.

@andrewgiessel
Copy link
Contributor Author

... good? the places i had to change things for the master rebase were in .travis.yml and the tests.

@themiurgo
Copy link
Contributor

Everything seems good, it's a merge! 🎉 Thanks for the nice contribution @andrewgiessel !

themiurgo added a commit that referenced this pull request Jul 30, 2015
@themiurgo themiurgo merged commit 746e3dc into python-visualization:master Jul 30, 2015
@BibMartin
Copy link
Contributor

Congrats @andrewgiessel, @themiurgo ; good contribution (and tricky git moves)

@andrewgiessel
Copy link
Contributor Author

🎉 🎉 🎉 👏 👏 👏 😎 😎 😎

@ocefpaf ocefpaf mentioned this pull request Aug 5, 2015
@ocefpaf ocefpaf mentioned this pull request Aug 24, 2015
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.

None yet

4 participants