diff --git a/folium/features.py b/folium/features.py
index 587f5e053b..2a38e74c57 100644
--- a/folium/features.py
+++ b/folium/features.py
@@ -1888,7 +1888,8 @@ class CustomIcon(Icon):
* Otherwise a string will be assumed to be JSON and embedded.
* If array-like, it will be converted to PNG base64 string and embedded.
icon_size : tuple of 2 int, optional
- Size of the icon image in pixels.
+ Size of the icon image in pixels. If not given, the image is shown
+ at its natural size.
icon_anchor : tuple of 2 int, optional
The coordinates of the "tip" of the icon
(relative to its top left corner).
diff --git a/folium/map.py b/folium/map.py
index daf7ee84cb..7f08da9884 100644
--- a/folium/map.py
+++ b/folium/map.py
@@ -509,8 +509,21 @@ class Marker(MacroElement):
class SetIcon(MacroElement):
"""Set the icon of a marker after both are created."""
+ # Leaflet reuses the current
element when the new icon is also an
+ # image, and keeps its inline size and margins if the new icon does not
+ # set them. Clear them first, so an icon without `icon_size` keeps the
+ # natural size of its image instead of the size of the default icon.
_template = Template("""
{% macro script(this, kwargs) %}
+ {
+ const element = {{ this.marker.get_name() }}.getElement();
+ if (element) {
+ element.style.width = "";
+ element.style.height = "";
+ element.style.marginLeft = "";
+ element.style.marginTop = "";
+ }
+ }
{{ this.marker.get_name() }}.setIcon({{ this.icon.get_name() }});
{% endmacro %}
""")
diff --git a/tests/test_map.py b/tests/test_map.py
index 594c42ce0e..1cebf9c2fb 100644
--- a/tests/test_map.py
+++ b/tests/test_map.py
@@ -305,6 +305,24 @@ def test_marker_numpy_array_as_location():
Marker(np.array([0, 0]))
+def test_set_icon_clears_size_of_previous_icon():
+ # Leaflet reuses the
of the default icon, so its inline size must be
+ # cleared for a custom icon without icon_size to keep its natural size.
+ from folium.features import CustomIcon
+
+ m = Map()
+ marker = Marker([0, 0], icon=CustomIcon("https://example.com/logo.png"))
+ marker.add_to(m)
+ script = normalize(m.get_root().render())
+ element = f"{marker.get_name()}.getElement()"
+ set_icon = f"{marker.get_name()}.setIcon({marker.icon.get_name()});"
+ assert element in script
+ assert set_icon in script
+ assert script.index(element) < script.index(set_icon)
+ for prop in ("width", "height", "marginLeft", "marginTop"):
+ assert f'.style.{prop} = "";' in script
+
+
def test_icon_hex_marker_color():
with warnings.catch_warnings():
warnings.simplefilter("error")