Mittenchops
Mittenchops

Reputation: 19654

Export a folium map as a png

I'm working with a map created using python, folium, and geojson, similar to this one.

However, instead of this image being an interactive HTML document, I would rather simply export it to png or svg.

Using the syntax:

m = folium.Map( # etc..)
m.save("filename.png")

Saves a file, but it is still HTML, rather than png. What's the correct output command to render not-to-html?

Upvotes: 30

Views: 64158

Answers (4)

cconsta1
cconsta1

Reputation: 835

For anyone who needs to convert a folium map to PNG in Google Colab here is what worked for me:

  1. Install selenium by running this cell:
!pip install selenium
  1. Then assuming map is your folium map run:
import io
from PIL import Image
import selenium

img_data = map._to_png(5)
img = Image.open(io.BytesIO(img_data))
img.save('image.png')
  1. To download the map on your local machine:
from google.colab import files
files.download('image.png')

Upvotes: 2

Austin Moore
Austin Moore

Reputation: 11

After working through this same problem I found this solution using pdfkit, wkthmltopdf, and fitz, yet without SElENIUM or anything else that requires opening a browser (I’ve been challenging myself by only coding on my IPhone/IPad with Google Colab): Convert Folium Map to PNG Without SELENIUM.

First I converted the folium map from HTML to PDF using pdfkit, then I converted the PDF to PNG using fitz & cut the image out using pillow.

Its hacky and could use a lot of improvement, but it works for me now.

More details in the Colab link above.

def convert_map_png(folium_map, file_name):
  mapName = file_name
  
  # Get HTML File of Map
  folium_map.save(mapName + '.html')
  htmlfile = mapName + '.html'

  # Convert Map from HTML to PDF, Delay to Allow Rendering
  options = {'javascript-delay': 500,
    'page-size': 'Letter',
    'margin-top': '0.0in',
    'margin-right': '0.0in',
    'margin-bottom': '0.0in',
    'margin-left': '0.0in',
    'encoding': "UTF-8",
    'custom-header': [
        ('Accept-Encoding', 'gzip')
    ]}
  pdfkit.from_file(htmlfile,  (mapName + '.pdf'), options=options)
  pdffile = mapName + '.pdf'

  # Convert Map from PDF to PNG
  doc = fitz.open(pdffile)
  page = doc.load_page(0)
  pix = page.get_pixmap()
  output = mapName + '.png'
  pix.save(output)
  pngfile = mapName + '.png'
  doc.close()

  # Crop Out Map Image
  pilImage = Image.open(pngfile)
  
  croppedImage = pilImage.crop((0,0,287,287)) # Adjust this if your map renders differently on PDF

  return croppedImage

Upvotes: 0

K J
K J

Reputation: 11735

In such cases I find PrintScreen a boon its a one key programme but you can do similar by using the browser in headless screenshot mode too. Just much faster by hand. Not all options will be needed just my zealous overkill, as Edge only produced/output fixed size 800x600 image.

"C:\Apps\Browsers\GoogleChrome\GoogleChromePortable.exe" --headless --start-maximized --start-fullscreen --window-size="2000,1000" --hide-scrollbars --virtual-time-budget=5000 --screenshot="c:\Data\MySampleData\screen.png"  "C:\Data\MySampleData\map.html" &&timeout 6 &&screen.png

enter image description here

Upvotes: 1

Michel Metran
Michel Metran

Reputation: 591

I use this:

... where m is my map object. And 5 is the time (seconds) to render the map.

import io
from PIL import Image

img_data = m._to_png(5)
img = Image.open(io.BytesIO(img_data))
img.save('image.png')

Upvotes: 32

Related Questions