title: How to add categorical legend to Python Folium map?
body: <p>I would like to add a categorical/numerical legend to a folium map like <a href="https://www.rdocumentation.org/packages/leaflet/versions/2.0.3/topics/addLegend" rel="nofollow noreferrer">addLenged()</a> from R does.</p>
  <p>Examples:</p>
  <h2>Numerical legend</h2>
  <p><a href="https://i.stack.imgur.com/G6lwW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/G6lwW.png" alt="numeric legend" /></a></p>
  <p>I also would like to add a categorical legend like this:</p>
  <h2>Categorical legend</h2>
  <p><a href="https://i.stack.imgur.com/fNDBo.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fNDBo.png" alt="enter image description here" /></a></p>
  <p>For now I only have this code, I am stuck trying to achieve what addLegend from R does.</p>
  <h2>Function</h2>
  <pre><code>def add_categorical_legend(folium_map, title, colors, labels):
      if len(colors) != len(labels):
          raise ValueError(&quot;colors and labels must have the same length.&quot;)
  
      color_by_label = dict(zip(labels, colors))
      
      legend_categories = &quot;&quot;     
      for label, color in color_by_label.items():
          legend_categories += f&quot;&lt;li&gt;&lt;span style='background:{color}'&gt;&lt;/span&gt;{label}&lt;/li&gt;&quot;
          
      legend_html = f&quot;&quot;&quot;
      &lt;div id='maplegend' class='maplegend'&gt;
        &lt;div class='legend-title'&gt;{title}&lt;/div&gt;
        &lt;div class='legend-scale'&gt;
          &lt;ul class='legend-labels'&gt;
          {legend_categories}
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &quot;&quot;&quot;
      script = f&quot;&quot;&quot;
          &lt;script type=&quot;text/javascript&quot;&gt;
          var oneTimeExecution = (function() {{
                      var executed = false;
                      return function() {{
                          if (!executed) {{
                               var checkExist = setInterval(function() {{
                                         if ((document.getElementsByClassName('leaflet-top leaflet-right').length) || (!executed)) {{
                                            document.getElementsByClassName('leaflet-top leaflet-right')[0].style.display = &quot;flex&quot;
                                            document.getElementsByClassName('leaflet-top leaflet-right')[0].style.flexDirection = &quot;column&quot;
                                            document.getElementsByClassName('leaflet-top leaflet-right')[0].innerHTML += `{legend_html}`;
                                            clearInterval(checkExist);
                                            executed = true;
                                         }}
                                      }}, 100);
                          }}
                      }};
                  }})();
          oneTimeExecution()
          &lt;/script&gt;
        &quot;&quot;&quot;
     
  
      css = &quot;&quot;&quot;
  
      &lt;style type='text/css'&gt;
        .maplegend {
          z-index:9999;
          float:right;
          background-color: rgba(255, 255, 255, 1);
          border-radius: 5px;
          border: 2px solid #bbb;
          padding: 10px;
          font-size:12px;
          positon: relative;
        }
        .maplegend .legend-title {
          text-align: left;
          margin-bottom: 5px;
          font-weight: bold;
          font-size: 90%;
          }
        .maplegend .legend-scale ul {
          margin: 0;
          margin-bottom: 5px;
          padding: 0;
          float: left;
          list-style: none;
          }
        .maplegend .legend-scale ul li {
          font-size: 80%;
          list-style: none;
          margin-left: 0;
          line-height: 18px;
          margin-bottom: 2px;
          }
        .maplegend ul.legend-labels li span {
          display: block;
          float: left;
          height: 16px;
          width: 30px;
          margin-right: 5px;
          margin-left: 0;
          border: 0px solid #ccc;
          }
        .maplegend .legend-source {
          font-size: 80%;
          color: #777;
          clear: both;
          }
        .maplegend a {
          color: #777;
          }
      &lt;/style&gt;
      &quot;&quot;&quot;
  
      folium_map.get_root().header.add_child(folium.Element(script + css))
  
      return folium_map
  </code></pre>
  <h2>Reproducible example</h2>
  <pre><code>import folium
  m = folium.Map()
  
  m = add_categorical_legend(m, 'My title',
                               colors = ['#000','#03cafc'],
                             labels = ['Heat', 'Cold'])
  m = add_categorical_legend(m, 'My title 2',
                               colors = ['#F23','#777'],
                             labels = ['Heat 2', 'Cold 2'])
  m.save(&quot;map.html&quot;)
  m
  </code></pre>
  <h2>Result</h2>
  <p><a href="https://i.stack.imgur.com/3Tm9A.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3Tm9A.png" alt="enter image description here" /></a></p>
  <h2>Problems</h2>
  <ul>
  <li>However the legend I have made conflicts with folium LayerControls and they stop working which for me is a very big problem because legends are for describing what I am using in LayerControls. I don't know what is the reason.</li>
  <li>Also this only works for categorical data.</li>
  </ul>
  <h2>Important</h2>
  <ul>
  <li>I would like that legends could be added to top | bot &amp; right | left positions like addLegend from R does. Giving absolute position is not an option.</li>
  </ul>
  <h3>Any help is appreciated</h3>
  <p>NOTE: I don't want to use branca color map because I would like to have a legend like a have shown you in the images</p>