Importing an svg file into a matplotlib figure

20,835

Solution 1

Maybe what you are looking for is svgutils

import svgutils.compose as sc
from IPython.display import SVG # /!\ note the 'SVG' function also in svgutils.compose
import numpy as np

# drawing a random figure on top of your SVG
fig, ax = plt.subplots(1, figsize=(4,4))
ax.plot(np.sin(np.linspace(0,2.*np.pi)), np.cos(np.linspace(0,2.*np.pi)), 'k--', lw=2.)
ax.plot(np.random.randn(20)*.3, np.random.randn(20)*.3, 'ro', label='random sampling')
ax.legend()
ax2 = plt.axes([.2, .2, .2, .2])
ax2.bar([0,1], [70,30])
plt.xticks([0.5,1.5], ['water  ', ' ground'])
plt.yticks([0,50])
plt.title('ratio (%)')
fig.savefig('cover.svg', transparent=True)
# here starts the assembling using svgutils 
sc.Figure("8cm", "8cm", 
    sc.Panel(sc.SVG("./Worldmap_northern.svg").scale(0.405).move(36,29)),
    sc.Panel(sc.SVG("cover.svg"))
    ).save("compose.svg")
SVG('compose.svg')

Output:

enter image description here

Solution 2

to anyone ending up here in 2021...

I'd suggest having a look at the cairosvg package
(conda install -c conda-forge cairosvg)

https://cairosvg.org/

import cairosvg
import matplotlib.pyplot as plt
from PIL import Image
from io import BytesIO

img = cairosvg.svg2png("... the content of the svg file ...")
img = Image.open(BytesIO(img_png))
plt.imshow(img)
Share:
20,835

Related videos on Youtube

Sasha
Author by

Sasha

Hy everyone! I am a physicist and a Linux enthusiast mostly coding in python for scientific purposes.

Updated on July 19, 2022

Comments

  • Sasha
    Sasha almost 2 years

    I like to produce high quality plots and therefore avoid rasterized graphics as much as possible.

    I am trying to import an svg file on to a matplotlib figure:

    import matplotlib.pyplot as plt
    earth   = plt.imread('./gfx/earth.svg')
    fig, ax = plt.subplots()
    im      = ax.imshow(earth)
    plt.show()
    

    This works with png perfectly. Can somebody tell me how to do it with svg or at least point my to proper documentation.

    I know that a similar question has been asked (but not answered): here. Has anything changed since?

    P.S. I know that I could just export a high resolution png and achieve a similar effect. This is not the solution I am looking for.

    Here is the image I would like to import:

    Earth_from_above .

    • jadsq
      jadsq about 5 years
      A quick side note: if you're interested in plotting data on a map there is the cartopy package that is specialised in just that.
  • Sasha
    Sasha almost 9 years
    Thank you for the reply. However, from my question, you could have seen that I have an understanding of the characteristics of the two formats. I also explicitly stated that everything works fine with a png. Furthermore, matplotlib works with paths. Every time you save an image as eps or svg, you are saving vector graphics. Most plots, before you save them, are vector graphics which can be scaled arbitrarily.
  • rubenvb
    rubenvb almost 9 years
    Matplotlib might work with paths internally just like svg, but two things working with paths does not imply those two things working together. Note I also suggested generating the matplotlib figure separately and merging them in a second manual or scripted step. Unless you dive into the Matplotlib artists and are prepared to parse the svg file manually, I strongly doubt you'll be able to let Matplotlib use the file as a background.
  • Sasha
    Sasha almost 9 years
    I did not think it is that complicated, will try to see how the parsing thing works. Could you edit your answer so that I can up-vote it?
  • rubenvb
    rubenvb almost 9 years
    @Sasha there, done. Please refrain from downvoting too soon to prevent this kind of situation.
  • Alexandre Strube
    Alexandre Strube about 4 years
    I am confused, since I can export from Matplotlib as svg, but I can't read back
  • Andreas
    Andreas over 2 years
    Thank you, this worked very well!
  • Martin Gardfjell
    Martin Gardfjell almost 2 years
    I couldn't import cairosvg. Error message: OSError: no library called "cairo-2" was found no library called "cairo" was found no library called "libcairo-2" was found cannot load library 'libcairo.so.2': error 0x7e cannot load library 'libcairo.2.dylib': error 0x7e cannot load library 'libcairo-2.dll': error 0x7e