Lucas
Lucas

Reputation: 7341

Hover in popup in Folium

With a simple example like this:

import folium

map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12,
                   tiles='Stamen Terrain')
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows').add_to(map_1)
map_1

Can you make a popup appear just by putting the mouse up? Is this possible with folium?

Upvotes: 3

Views: 12459

Answers (5)

kgoodrick
kgoodrick

Reputation: 883

If the tooltip functionality is not sufficient (e.g. you want to include a table or chart in the popup) you can modify the Popup class to add the lines mentioned in this answer.

from folium import Popup
from folium.features import Template

class HoverPopup(Popup):
    _template = Template(
        """
        var {{this.get_name()}} = L.popup({{ this.options|tojson }});

        {% for name, element in this.html._children.items() %}
            {% if this.lazy %}
                {{ this._parent.get_name() }}.once('click', function() {
                    {{ this.get_name() }}.setContent($(`{{ element.render(**kwargs).replace('\\n',' ') }}`)[0]);
                });
            {% else %}
                var {{ name }} = $(`{{ element.render(**kwargs).replace('\\n',' ') }}`)[0];
                {{ this.get_name() }}.setContent({{ name }});
            {% endif %}
        {% endfor %}

        {{ this._parent.get_name() }}.bindPopup({{ this.get_name() }})
        {% if this.show %}.openPopup(){% endif %};
        
        // New code *************
        {{ this._parent.get_name() }}.on('mouseover', function (e) {
            this.openPopup();
        });
        {{ this._parent.get_name() }}.on('mouseout', function (e) {
            this.closePopup();
        });
        // End new code *************

        {% for name, element in this.script._children.items() %}
            {{element.render()}}
        {% endfor %}
    """
    ) 

You can then use it just like a normal popup

import folium

map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12)

hp = HoverPopup('Mt. Hood Meadows')
folium.Marker([45.3288, -121.6625], popup=hp).add_to(map_1)
map_1

The advantage to this answer compared with previous ones is that it does not require modifying the HTML after the fact and will work in environments like Jupyter notebooks.

If you have interactivity in your popup you can remove the following lines and it will not disappear when the mouse moves off the marker. The user can then close the popup with the x or by clicking on the map.

{{ this._parent.get_name() }}.on('mouseout', function (e) {
    this.closePopup();
});

Upvotes: 0

Jealie
Jealie

Reputation: 6277

UPDATED ANSWER

It turns out that this functionality has been put into folium's codebase.

Simply add the tooltip argument, like so:

import folium

map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12, tiles='Stamen Terrain',
                   tooltip = 'This tooltip will appear on hover' # THIS
                  )
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows').add_to(map_1)
map_1

Upvotes: 7

Duc Vu
Duc Vu

Reputation: 57

In the example below, popup opens on mouse-over, not on click, and hide it when the user mouses out:

map_1.save('map_1.html')
import re
import fileinput

with open("map_1.html") as inf:
   txt = inf.read()

#Find all the markers names given by folium
markers = re.findall(r'\bmarker_\w+', txt)
markers = list(set(markers))

for linenum,line in enumerate( fileinput.FileInput("map_1.html",inplace=1) ):
    pattern = markers[0] + ".bindPopup"
    pattern2 = markers[0] + ".on('mouseover', function (e) {this.openPopup();});"
    pattern3 = markers[0] + ".on('mouseout', function (e) {this.closePopup();});"

    if pattern in line:
       print(line.rstrip())
       print(pattern2)
       print(pattern3)
    else:
       print(line.rstrip())

Upvotes: 2

You can't do it easily from folium. But since folium does create LeafletJS code you can modify the output to make it work. For that you will have to add to the resulting html the code stated in this answer:

    marker.bindPopup("Popup content");
    marker.on('mouseover', function (e) {
        this.openPopup();
    });
    marker.on('mouseout', function (e) {
        this.closePopup();
    });

If you have many markers this might become a difficult task, but you can do it through python (though it will not look pretty). Pseudocode:

import re

with open("map.html") as inf:
    txt = inf.read()

#Find all the markers names given by folium
markers = re.findall(r'\bmarker_\w+', txt)

for marker in markers:
   # Add the code given before to the string txt

# Save the new map
with open("new_map.html", "w") as outf:
    outf.write(txt)

This codes opens the generated html file, find all the markers, and adds the code for each marker.

Upvotes: 3

Nevermore
Nevermore

Reputation: 7409

Your question is asking about folium, and I don't think so, but I think you can add some Javascript (with jquery it'd be super easy I suspect), to simulate a click event onmouseover or mouseenter

  var test = document.getElementById("test");

  test.addEventListener("mouseenter", handlerClickFunction);

Upvotes: 1

Related Questions