grass.jupyter: Created attracting and elegant legend feature for rasters in InteractiveMap.#7077
grass.jupyter: Created attracting and elegant legend feature for rasters in InteractiveMap.#7077shahid-rahaman wants to merge 6 commits intoOSGeo:mainfrom
Conversation
f0b4776 to
e568a16
Compare
|
Reproducible code examples and screenshots? |
@wenzeslaus Sorry for late reply, I have updated the description. I have been facing some dev system crash. Is there any standard way to setup dev environment? I somehow did but it was quirky, I installed grass from local repo by ./configure>make -j10> sudo make install, but it throws few errors sometimes due to which I cannot run local test/checks as it is not installed properly. Am I missing something or is there any documentation to setup dev enviroment? |
wenzeslaus
left a comment
There was a problem hiding this comment.
Well, the legend in screenshots does look attractive and elegant.
Anyway, you should still make the title shorter and more technical.
More work is needed here and I did not test myself yet, but I like the direction here.
| from branca.element import MacroElement | ||
| from jinja2 import Template |
There was a problem hiding this comment.
This will need to be handled more carefully. Neither of those is our current direct dependency. jinja2 is used here and there for special things (like tests and addon tools) and we likely bring that in with folium (I did not check). However, branca is not the most active project and it is still <1.0.
| border: 1px solid rgba(0, 0, 0, 0.2); | ||
| border-radius: 12px; | ||
| color: black; | ||
| font-family: 'Segoe UI', Arial, sans-serif; |
There was a problem hiding this comment.
There is no user-specified font anywhere here? There is a font used for the 2D rendering (for the non-interactive Map). There is always GRASS_FONT env var which is meant for display/rendering so this would not be too far from the current use.
There was a problem hiding this comment.
@wenzeslaus There is indeed a fontcap file which contain fonts, but how to use them. I can make provision for user specified fonts but for instance if the font is "cyrilic", we cannot put it in CSS, these are .hmp files. Am I missing something?
regards
There was a problem hiding this comment.
See actual usages of GRASS_FONT in the code (now I see the doc does not include all cases), but yes, if it is a local path, then don't pass it here.
|
@wenzeslaus Thanks for your time, I understand there are some preferred approach for GRASS, I used python core logics and module to make it work, like "subprocess", I had used it several times personally. However, I will try align the code with the existing dependencies and preferred approach. |
|
Please, sync up to the main branch. Then, the following link will allow reviewers to test without the need to have the changes locally: |
|
I didn't get any legend on mobile. |
605bd3f to
939dcaf
Compare
939dcaf to
cbb28e3
Compare
| from branca.element import MacroElement | ||
| import folium | ||
| from folium.map import MacroElement | ||
| from jinja2 import Template |
There was a problem hiding this comment.
@wenzeslaus You earlier worried about these dependencies, but both of them are the dependencies of of folium itself See.
Folium has the following dependencies, all of which are installed automatically with the above installation commands:
branca, Jinja2, Numpy ,Requests
However, I avoided branca, as it is not very active but we can use jinja as it is already installed. Folium internally calles Template() method of jinja to create Template object. And this object is essential as it further calls for module attribute associate with this object. So, far it is working fine as expected as per my observation.
There was a problem hiding this comment.
This looks good. While it is not bulletproof, transitive vs direct dependency makes as difference.
@wenzeslaus I have not checked it on the phones yet. I am not sure if phones allows html code to be injected the same way. Although, in chrome dev tool when I toggle the device to be iphone 12 or responsive, I see the legend there. So, I think it is the not the resolution problem. |
|
@wenzeslaus Any update here? |
wenzeslaus
left a comment
There was a problem hiding this comment.
I like this and I get the legend in Binder at least with a desktop. However, there is couple of issues here:
- Now, I always get a viridis. The logic is wrong.
- The gradient values taken from GRASS may not work as is with CSS as visible in the image - at least in Firefox (see above).
- Your previous examples were much better. Also add geology. Make them copy-pastable to the notebooked used in Binder. Test your result as if you would be a user. Use a tutorial.
- See my other comments.
Just a heads-up that this starts to feel like interacting with AI. Please, review our AI policy in the contributing file.
| self.layer_control_object = self._ipyleaflet.LayersControl(**kwargs) | ||
|
|
||
| def add_legend(self, raster, color="viridis", position="bottomright"): | ||
| from grass.tools import Tools |
There was a problem hiding this comment.
Top-level import. For, mpl, I'm not sure. How we import it elsewhere?
There was a problem hiding this comment.
mpl is redundant here, I used it for a different approach to create gradient color strip but the approach was not dyanamic later I forgot to remove it. For grass tools I think importing here is good, importing only when legend is required. ALthough, wherever you say I will place it.
| # Setting color scheme for raster rendering | ||
| tools.r_colors(map=raster, color=color) |
There was a problem hiding this comment.
This is problematic. With the current way how color tables are handled, this needs to be done by the caller, not here.
| # Joining the retrieved colors to form smooth gradient. | ||
| colors = [item["color"] for item in color_maps] | ||
| css_gradient = ", ".join(colors) |
There was a problem hiding this comment.
This now does not have the previous functionality. Illogical, too much AI?
| colors = [item["color"] for item in color_maps] | ||
| css_gradient = ", ".join(colors) | ||
| # Setting some interval ticks to compare values relatively. | ||
| info = tools.r_info(map=raster, format='json') |
There was a problem hiding this comment.
Explore what you get with the r_colors_out call, r_info, and r_univar for the range of values for different computational regions (after changing the extent by g_region/g.region user-level call to change the extent which will change what values are considered). This influenced whether or not the r_info call here appropriate.
| font-weight: bold; | ||
| color: black; | ||
| "> | ||
| {info["title"]} |
There was a problem hiding this comment.
This needs a fallback to the previously used name.
@wenzeslaus Thanks for review. Very first thing I don't trust AI generated code they are very often poorly strcutured and redundant. Although I use LLMs for code review and guidance, like where to find the appropriate info in the documentation. Now, lets, come to your concerns.
But I dont know why binder shows "rainbow" colors as you have not provided any color arguments and default is "viridis". And there is indeed a bug I am working on that is when a color scheme is applied it is somehow saved in cache or something(I am not sure yet) but when you refresh the same cell it renders the rasters with desired colors. I should see some binder usage.
|
The geology map in that sample dataset has colors already set (it may be indeed rainbow). Importantly, the resulting color table is not a gradient one. The values are categorical. Run r.report to understand more about this specific data. Compare to elevation. Aspect may be yet a little different.
viridis is used as a default internally. No work from users or in your code is needed. I hope this clarifies that.
The color table is saved with the data in the GRASS project, so in a way, r.colors call modifies the data (or let's say visualization metadata), so that's why you should not be using it in the code (you should have an example which uses that, though). Generate new data with r.surf.fractal to get an example for that use case. |


Created legend feature for rasters with easy to use commands. Gave it a transparent glass frost look for better UX.
@wenzeslaus If looks good to you, I will write the tests for the corresponding entities.
Let me know if requires any adjustments.
For instance, use it like below.
Viridis Style Position bottom left

Viridis Style Position bottom right

Magma Style Position bottom right

You can use any colors like sepia, rainbow, etc. apart from viridis and magma.
regards