In [50]:
pip install folium
Requirement already satisfied: folium in /opt/conda/lib/python3.13/site-packages (0.20.0) Requirement already satisfied: branca>=0.6.0 in /opt/conda/lib/python3.13/site-packages (from folium) (0.8.2) Requirement already satisfied: jinja2>=2.9 in /opt/conda/lib/python3.13/site-packages (from folium) (3.1.6) Requirement already satisfied: numpy in /opt/conda/lib/python3.13/site-packages (from folium) (2.3.3) Requirement already satisfied: requests in /opt/conda/lib/python3.13/site-packages (from folium) (2.32.5) Requirement already satisfied: xyzservices in /opt/conda/lib/python3.13/site-packages (from folium) (2025.4.0) Requirement already satisfied: MarkupSafe>=2.0 in /opt/conda/lib/python3.13/site-packages (from jinja2>=2.9->folium) (3.0.3) Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (3.4.4) Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (3.11) Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (2.5.0) Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (2025.10.5) Note: you may need to restart the kernel to use updated packages.
In [44]:
import pandas as pd
# ---------- CONFIG ----------
INPUT_CSV = "beers_geocoded.csv"
OUTPUT_HTML = "yerevan_beer_map.html"
BEER_COLS = {
"vl": "Vienna Lager",
"p": "Pilsner",
"d": "Dunkel",
}
# Mapping of code → label & color
BEER_META = {
"vl": {"label": "Vienna Lager", "color": "rgba(0, 180, 0, 0.85)"}, # green
"p": {"label": "Pilsner", "color": "rgba(240, 210, 0, 0.85)"}, # yellow
"d": {"label": "Dunkel", "color": "rgba(0, 0, 0, 0.85)"}, # black
}
# 1. Load data
data = pd.read_csv(INPUT_CSV)
data = data.dropna(subset=["lat", "lon"])
data
Out[44]:
| number | name | address | vl | p | d | lat | lon | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | Krish Ka | Երևան, Տիգրանյան 11/3 | True | True | True | 40.202911 | 44.513956 |
| 1 | 2 | Be Friends Gastronomy & Gathering Spot | Երևան, Ադոնցի 6 | True | True | True | 40.212775 | 44.523152 |
| 2 | 3 | Like Beer | Երևան, Դավթաշեն 2, 43/3 | True | False | False | 40.225442 | 44.493972 |
| 3 | 4 | Tun Lahmajo | Երևան, Տերյան 25 | True | False | False | 40.182997 | 44.514405 |
| 4 | 5 | Green Beer | Երևան, Սվաճյան 26 | True | True | False | 40.175520 | 44.447221 |
| 5 | 6 | Լցնովի գարեջուր | Երևան, Բանավան 1/60 | True | False | False | 40.187699 | 44.593381 |
| 6 | 7 | Liquor & More | Երևան, Ջրվեժ 16-րդ 3 | True | True | False | 40.186292 | 44.592413 |
| 7 | 8 | Լցնովի գարեջուր ? | Երևան, Կոմիտաս 63 | True | True | False | 40.206505 | 44.523905 |
| 8 | 9 | Լցնովի գարեջուր ? | Կոտայքի մարզ, Նոր Հաճն, Չարենցի 16 21 | True | False | False | 40.303364 | 44.583066 |
| 9 | 10 | Beer House | Արմավիրի մարզ, Արմավիր, Երևանյան 42/21 | True | False | False | 40.151594 | 44.026236 |
In [42]:
def beers_for_row(row):
"""Return list of beer codes present for this row, in fixed order vl, p, d."""
present = []
for code in ["vl", "p", "d"]:
if code in row.index and bool(row[code]):
present.append(code)
return present
def beer_icon_html(beer_codes):
"""
Build an inline SVG with 1/2/3 circles according to beer_codes.
beer_codes is a list like ["vl", "p"] in canonical order.
"""
# SVG canvas
svg_parts = ['<svg width="26" height="26" viewBox="0 0 26 26">']
n = len(beer_codes)
if n == 0:
# no beer → no circles, but still small transparent svg to anchor popup
svg_parts.append('</svg>')
svg = "".join(svg_parts)
return f'<div style="background: transparent;">{svg}</div>'
# Positions are chosen to look like “coconut holes”
# Radius slightly smaller so they don't overlap visually
if n == 1:
# Center circle
code = beer_codes[0]
color = BEER_META[code]["color"]
svg_parts.append(
f'<circle cx="13" cy="13" r="7" fill="{color}" />'
)
elif n == 2:
# Two circles side by side
positions = [(9, 13), (17, 13)]
for code, (cx, cy) in zip(beer_codes, positions):
color = BEER_META[code]["color"]
svg_parts.append(
f'<circle cx="{cx}" cy="{cy}" r="6" fill="{color}" />'
)
else:
# n >= 3 → use vl, p, d order, coconut pattern
# Top: first beer; bottom-left: second; bottom-right: third
positions = [(13, 9), (9, 17), (17, 17)]
for code, (cx, cy) in zip(beer_codes[:3], positions):
color = BEER_META[code]["color"]
svg_parts.append(
f'<circle cx="{cx}" cy="{cy}" r="5.8" fill="{color}" />'
)
svg_parts.append("</svg>")
svg = "".join(svg_parts)
# No background, no border; icon will be centered by icon_anchor
html = f'<div style="background: transparent;">{svg}</div>'
return html
In [59]:
import folium
# Define a location (latitude, longitude)
yvn = [ 40.1791857, 44.4991029 ] # Yerevan
""" Map scroll limitation
min_lon, max_lon = -45, -35
min_lat, max_lat = -25, -15
m = folium.Map(
max_bounds=True,
location=[-20, -40],
zoom_start=6,
min_lat=min_lat,
max_lat=max_lat,
min_lon=min_lon,
max_lon=max_lon,
)
"""
cute_map = folium.Map(location = yvn, tiles="Cartodb Positron", zoom_start=10) # Create an empty map ___ tiles="Cartodb Positron",
for i, row in data.iterrows():
lat = data['lat'][i]
lon = data['lon'][i]
beer_codes = beers_for_row(row)
beer_labels = [BEER_META[c]["label"] for c in beer_codes]
beers_text = ", ".join(beer_labels) if beer_labels else "—"
popup_html = f"""
<b>{row['name']}</b><br>
{row['address']}<br>
<b>Beers:</b> {beers_text}
"""
icon_html = beer_icon_html(beer_codes)
cute_icon = folium.DivIcon(
html=icon_html,
icon_size=(26, 26),
icon_anchor=(13, 13), # center the SVG on the location
class_name="beer-icon" # no default white background
)
folium.Marker(location = [lat, lon],
popup=popup_html,
icon = cute_icon
).add_to(cute_map)
cute_map
Out[59]:
Make this Notebook Trusted to load map: File -> Trust Notebook