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

replace GeoJsonStyle by kwarg style_function in GeoJson #266

Merged
merged 1 commit into from
Dec 4, 2015

Conversation

BibMartin
Copy link
Contributor

To simplify choropleth generation.

You have to provide a function feature -> style which is to me the most generic API.

I need to update Map.geo_json and tests before merge.

@ocefpaf ocefpaf mentioned this pull request Nov 28, 2015
@@ -184,22 +184,56 @@ def __init__(self, data):

# providing string
GeoJson(open('foo.json').read())
style_function: function, default None
A function mapping a GeoJson Feature to a style dict.
Ex: If you GeoJson has the form
Copy link
Member

Choose a reason for hiding this comment

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

If your

@ocefpaf
Copy link
Member

ocefpaf commented Nov 28, 2015

You have to provide a function feature -> style which is to me the most generic API.

I like that as a low level interface: powerful and simple. We just need to provide some high level methods wrapping that and, as you mention, the choropleth is the first obvious one.

I also think we should comply with the simple-spec by default. That would solve #198 and #120.

@BibMartin if I understood your implementation it would be a matter if writing a style_function for the simple-spec, correct? We can do that later once your implementation is complete. We just need to be clear in the docs that the style_function will expect leaflet defaults, like fillOpacity instead of fill-opacity.

PS: Another killer PR! Thanks!!

@themiurgo
Copy link
Contributor

I'm against this as it is now, unless you manage to convince me. 😀

In folium the name GeoJson has always been confused with Choroplets. I think this is a major error and it needs to be fixed soon. Naming this object GeoJsonStyle goes in the opposite direction. Perhaps ChoroplethStyle instead? A hint that this is not just GeoJson is that it has properties like "color domain", "range" and such. GeoJson is not about mapping values to colors.

In the end we want:

  • To be able to quickly import / export features as GeoJson.
  • That GeoJson follows simple-spec, as @ocefpaf . Let's look at http://geojson.io for reference. Folium should be the Python version of that, augmented with all the nice plugins it has already.
  • To be able to generate choroplet, but that should be handled by different methods than the GeoJson import / export.

Let me know what you think about this. 😄

@ocefpaf
Copy link
Member

ocefpaf commented Nov 30, 2015

In folium the name GeoJson has always been confused with Choroplets. I think this is a major error and it needs to be fixed soon.

Agreed. And we are working on that here.

Naming this object GeoJsonStyle goes in the opposite direction. Perhaps ChoroplethStyle instead?

This PR removes the GeoJsonStyle and adds a kwarg to style the GeoJSON for any purpose and not only choropleth, so I do not think any renaming is necessary.

A hint that this is not just GeoJson is that it has properties like "color domain", "range" and such. GeoJson is not about mapping values to colors.

But that is styling that goes in the GeoJSON when plotting.

  • To be able to quickly import / export features as GeoJson.
  • That GeoJson follows simple-spec, as @ocefpaf . Let's look at http://geojson.io for reference. Folium should be the Python version of that, augmented with all the nice plugins it has already.

And I believe that this implementation, with a default set to comply with the simple-spec, achieve this goal. What do you think @BibMartin?

  • To be able to generate choroplet, but that should be handled by different methods than the GeoJson import / export.

Why not just another styling function that we can, and should, add another method that call this class and pass a styling function for easy choropleth generation.

Note that we do not need to force anything beyond the simple-spec as the default, but if people have wonky JSONs styles then have the tool to pass them here.

@BibMartin
Copy link
Contributor Author

With this PR, you can:

  • Put a GeoJson on the map, with GeoJson(my_geojson).
  • If my_geojson features have an attribute properties.style expressed in Leaflet style syntax, it will be taken into account on the map. It can be used for choropleth, but also for various reasons.
  • You can overwrite (update) the attributes properties.style in providing a styling function : GeoJson(my_geojson, my_style_function).
  • You can use the old Map.geo_json method to draw a choropleth. I'm okay with both of you to rename it choropleth ; but I would take the occasion to change it's API.

@ocefpaf

like that as a low level interface: powerful and simple. We just need to provide some high level methods wrapping that and, as you mention, the choropleth is the first obvious one.

True. I imagine we shall have the GeoJson object for low-level, and a Map.choropleth method for high-level choropleth. I've just kept the Map.geo_json name for backward-compatibility, but I'm okay to move it asap to Map.choropleth.

I also think we should comply with the simple-spec by default. That would solve #198 and #120.
@BibMartin if I understood your implementation it would be a matter if writing a style_function for the simple-spec, correct?

I did not thought about creating a simple-style style_function ; that'd be a great simple way of doing it. But honestly, I'm not comfortable with simple-style because

  • there are things belonging to mapbox
  • it does more than just styling (it creates Icons, popups, etc)
  • it creates another syntax, while Leaflet has it's own

If you're okay, I would at least let the simple-style part for another PR.

@ocefpaf
Copy link
Member

ocefpaf commented Nov 30, 2015

I did not thought about creating a simple-style style_function ; that'd be a great simple way of doing it. But honestly, I'm not comfortable with simple-style because

  • there are things belonging to mapbox

Yes, but I believe that the simple-spec is more wide spread than Leaflet's defaults. I see it a lot in many different mapping clients.

  • it does more than just styling (it creates Icons, popups, etc)

That is desirable sometimes. Like the choropleth stuff: range, color domain, etc 😉

  • it creates another syntax, while Leaflet has it's own

Maybe that is the real question. What should be folium's default? simple-spec or Leaflet's standards? I am inclined to simple-spec. However, since PR makes it easy to provide styling functions, maybe we can provide the simple-spec function as a built-in option. Not sure 😑

If you're okay, I would at least let the simple-style part for another PR.

Yes. I am OK with that. You already have a rebase on your plate 😜

@BibMartin
Copy link
Contributor Author

  • it does more than just styling (it creates Icons, popups, etc)

That is desirable sometimes. Like the choropleth stuff: range, color domain, etc 😉

I'm okay, but it means that we cannot support the full spec with this object. We need to have a style object that can contain a Icon, Popup and so on. I'll think about how to do it simply for another PR.

As for this PR, do I break the geo_json method API immediatly in favor of a choropleth ?

@ocefpaf
Copy link
Member

ocefpaf commented Nov 30, 2015

I'm okay, but it means that we cannot support the full spec with this object. We need to have a style object that can contain a Icon, Popup and so on.

That is fine. I though something along the lines of mapping fillOpacityfill-opacity, etc, while just ignoring Icons/Popups and other stuff that do not map directly.

Maybe, under that light, the simplespec should not be the default.

We can still implement a simple-spec styling function and provide it as an option. That function would be the first step to adding a simple-spec GeoJSON. And we can think about implementing this mapping style function + some Icon/Pop loop that would make a "simple-spec method." To me that is another 👍 to the robustness of this PR.

@BibMartin
Copy link
Contributor Author

It is (painfully) rebased ; and ready to merge.
Unless you want to take the occasion to replace

def geo_json(...):
    """

by

def geo_json(**kwargs):
    warnings.warn('This method is deprecated. Please use Map.choropleth instead.')
    return self.choropleth(**kwargs)

def choropleth(...):
    """

I can do it before squashing.

@@ -169,7 +169,7 @@ def render(self, **kwargs):


class GeoJson(MacroElement):
def __init__(self, data):
def __init__(self, data, style_function=None):
Copy link
Member

Choose a reason for hiding this comment

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

We still need to add a slim version of the simple-spec option. I am OK doing that in another PR. Let's just open an issue to keep track. (Or a new comment on the current issues we have open about the simple-spec.)

@ocefpaf
Copy link
Member

ocefpaf commented Dec 2, 2015

It is (painfully) rebased

Sorry. I won't wait so long to review typos and pep8 style. (And I should not do that when we have many PRs pending.)

Unless you want to take the occasion to replace

I think we are better off doing that in another PR.

I made a quick review. Nothing important.

Let me know if you want to address those here or if you want me to do those later.

@themiurgo are you in peace with this PR or do you still have some doubts? Your comments are valuable to us!

I am 👍 to merge this PR.

@themiurgo
Copy link
Contributor

I'm mainly ok. I'm not 100% ok with the name, but let's include it and see how it work out in the future. 👍

@themiurgo
Copy link
Contributor

I did not thought about creating a simple-style style_function ; that'd be a great simple way of doing it. But honestly, I'm not comfortable with simple-style because

  • there are things belonging to mapbox
  • it does more than just styling (it creates Icons, popups, etc)
  • it creates another syntax, while Leaflet has it's own

I hear your concerns, but at the moment simplespec-style is the only standard, the naming used by Leaflet is not a standard, it is tied to their javascript implementation and nobody uses it outside Leaflet. Also, siplespec-style is increasingly used in many places, including GitHub (a non-exaustive list:
https://github.com/mapbox/simplestyle-spec/wiki/Implementations). I think folium needs to be easily extendable and customizable, but have sane defaults. simplespec-style is part of the sane defaults in my opinion.

@BibMartin
Copy link
Contributor Author

Thanks @themiurgo and @ocefpaf for the review.

@ocefpaf

Let me know if you want to address those here or if you want me to do those later.

I'll try to apply changes tonight (CET) and squash in the same time.

@ocefpaf
Copy link
Member

ocefpaf commented Dec 2, 2015

I'll try to apply changes tonight (CET) and squash in the same time.

No rush. Just ping me once you are done.

@themiurgo
Copy link
Contributor

@BibMartin Could you please squash everything, so that I can merge? :)

@BibMartin
Copy link
Contributor Author

Could you please squash everything, so that I can merge? :)

Done.

Three remarks (before @ocefpaf will pep8 this) 😄

My pep8ing, breaking, and scrambling coding skills are everywhere! No code line is safe 👻

Yes, that's why challenging PEP8 before merge is a good habit. Maybe one day I'll be able to write PEP8-complianty code directly. Thanks to both of you for review, and thanks @ocefpaf for 👻

@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

@BibMartin can we do something about the None in the colorbar?

folium

def geo_json(self, geo_path=None, geo_str=None, data_out='data.json',
def geo_json(self, *args, **kwargs):
"""This method is deprecated, see `Map.choropleth` instead."""
warnings.warn('This method is deprecated. Please use Map.choropleth instead.')
Copy link
Member

Choose a reason for hiding this comment

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

Let's add and will be removed in v0.2.1

@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

To deal with the None let's just do

        legend_name: string, default empty string

Copy-and-paste docstring update too 😉

@BibMartin
Copy link
Contributor Author

I had it for None-> "" but forgot about the docstring

@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

Let me update my branch and try again. I got that None yesterday.

PS: do you think you can rebase this to get the _repr_html() fix?

@BibMartin
Copy link
Contributor Author

If you're finished, I do an extra commit and wait for your feedback before re-squashing

What repr_html fix ?

@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

From #275. Just because I am lazy and it will make it easier to see the results on the notebook.

@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

Just re-run all my notebooks that uses choropleths and they look awesome!

@BibMartin great work! And sorry for the last minute burst review. Squash?
@themiurgo Now am I done 😳 I promise no more teasing for a merge and then asking for changes 😜

@themiurgo
Copy link
Contributor

It'd be great if this could be squashed again. Sorry @BibMartin you can blame it on @ocefpaf 😜

@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

Sorry @BibMartin you can blame it on @ocefpaf 😜

I take all the blame as long as @BibMartin keeps sending awesome PRs 😸

@BibMartin
Copy link
Contributor Author

Squashed (sorry for the 2 hours delay ; I was in a meeting)

@themiurgo
Copy link
Contributor

Merge! Congrats to @BibMartin and thanks to @ocefpaf for the comments.

@themiurgo themiurgo closed this Dec 4, 2015
@themiurgo themiurgo reopened this Dec 4, 2015
themiurgo added a commit that referenced this pull request Dec 4, 2015
Replace GeoJsonStyle by kwarg style_function in GeoJson
@themiurgo themiurgo merged commit 1366528 into python-visualization:master Dec 4, 2015
@ocefpaf
Copy link
Member

ocefpaf commented Dec 4, 2015

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature request or idea about how to make folium better
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants