Skip to content

grass.jupyter: Created attracting and elegant legend feature for rasters in InteractiveMap.#7077

Open
shahid-rahaman wants to merge 4 commits intoOSGeo:mainfrom
shahid-rahaman:elegant-legend-for-rasters
Open

grass.jupyter: Created attracting and elegant legend feature for rasters in InteractiveMap.#7077
shahid-rahaman wants to merge 4 commits intoOSGeo:mainfrom
shahid-rahaman:elegant-legend-for-rasters

Conversation

@shahid-rahaman
Copy link

@shahid-rahaman shahid-rahaman commented Feb 11, 2026

Created legend feature for rasters with easy to use commands. Gave it a transparent glass frost look for better UX.
@petrasovaa 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.

from grass.jupyter import InteractiveMap
m = InteractiveMap(height=700, width = 1000)
m.add_raster("elevation")
m.add_legend("elevation")
m.show()

Elevation Map
elevation

from grass.jupyter import InteractiveMap
m = InteractiveMap(height=700, width = 1000)
m.add_raster("slope")
m.add_legend("slope")
m.show()

Slope Map
slope

from grass.jupyter import InteractiveMap
m = InteractiveMap(height=700, width = 1000)
m.add_raster("aspect")
m.add_legend("aspect")
m.show()

Aspect Map
aspect

regards

@shahid-rahaman shahid-rahaman force-pushed the elegant-legend-for-rasters branch from f0b4776 to e568a16 Compare February 11, 2026 22:36
@wenzeslaus
Copy link
Member

Reproducible code examples and screenshots?

@github-actions github-actions bot added Python Related code is in Python libraries notebook labels Feb 12, 2026
@shahid-rahaman
Copy link
Author

shahid-rahaman commented Feb 12, 2026

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?
regards

@shahid-rahaman shahid-rahaman changed the title Created attracting and elegant legend feature for rasters. grass.jupyter: Created attracting and elegant legend feature for rasters in InteractiveMap. Feb 12, 2026
Copy link
Member

@wenzeslaus wenzeslaus left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +388 to +391
all_colours = subprocess.check_output(f"r.colors.out map={raster}", shell=True).decode("utf-8").strip()
colors = {}
last_ht = None
for colour in all_colours.split("\n"):
Copy link
Member

Choose a reason for hiding this comment

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

There is an API for calling tools. Preferably, use the new grass.tools API and JSON output.

Comment on lines +392 to +399
if "nv" in colour or "default" in colour:
continue
elev_col_info = colour.split()
ht = float(elev_col_info[0])
rgb = elev_col_info[1]
label = f"{last_ht:.1f} - {ht:.1f} m" if last_ht else f"≤ {ht:.1f} m"
colors[label] = f"rgb({rgb.replace(':', ',')})"
last_ht = ht
Copy link
Member

Choose a reason for hiding this comment

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

While the result of this looks good for elevation and slope color tables in your screenshots, try with a viridis and magma color tables. Maybe you can sometimes use the r.colors.out output directly, while sometimes you need to take additional steps.

border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: black;
">
{raster.capitalize()} Map
Copy link
Member

Choose a reason for hiding this comment

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

A detail at this point, but since I noticed that: rasters have a title which would be the nice name for a legend. Use that instead of capitalize and name generation.

https://grass.osgeo.org/grass-devel/manuals/r.support.html
https://grass.osgeo.org/grass-devel/manuals/r.info.html

Comment on lines +472 to +473
from branca.element import MacroElement
from jinja2 import Template
Copy link
Member

Choose a reason for hiding this comment

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

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.

for item in reversed(list(self.map.layers)):
if isinstance(item, self._ipyleaflet.Popup):
self.map.remove(item)
self.map.remove(item) No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

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

Clean up your code and PRs.

border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 12px;
color: black;
font-family: 'Segoe UI', Arial, sans-serif;
Copy link
Member

Choose a reason for hiding this comment

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

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.

https://grass.osgeo.org/grass-devel/manuals/variables.html

@shahid-rahaman
Copy link
Author

@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.
regards

@wenzeslaus
Copy link
Member

Please, sync up to the main branch.

Then, the following link will allow reviewers to test without the need to have the changes locally:

https://mybinder.org/v2/gh/shahid-rahaman/grass/elegant-legend-for-rasters?urlpath=lab%2Ftree%2Fdoc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb

@shahid-rahaman
Copy link
Author

Please, sync up to the main branch.

Then, the following link will allow reviewers to test without the need to have the changes locally:

https://mybinder.org/v2/gh/shahid-rahaman/grass/elegant-legend-for-rasters?urlpath=lab%2Ftree%2Fdoc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb

I have synced it but getting libpdal error on this link but locally make worked fine without pdal. Am I doing something wrong?
Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libraries notebook Python Related code is in Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants