svg_utils icon indicating copy to clipboard operation
svg_utils copied to clipboard

`compose` creates empty figure

Open michaeldeistler opened this issue 3 years ago • 2 comments

OS: Ubuntu 20.04 LTS python: 3.8

Setup

I installed within a conda environment with:

sudo apt-get install libxml2-dev libxslt-dev
pip3 install svgutils --user

Problem

#!/usr/bin/env python
#coding=utf-8

from svgutils.compose import *
import matplotlib.pyplot as plt
import numpy as np

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)))
fig.savefig('cover.svg')

Figure("16cm", "6.5cm", 
    Panel(SVG('cover.svg')),
).save("composed.svg")

cover.svg looks correct, but composed.svg is a blank canvas. Interestingly, it works when using svgutils.transform

Quick fix

Downgrading to v0.3.1 works:

pip install svgutils==0.3.1

Is there anything I am doing obviously wrong or is this a bug?

michaeldeistler avatar Jun 16 '21 17:06 michaeldeistler

Okey, I just found that the created figure is in fact not empty, but the panel is just gigantically huge. The following works for me:

#!/usr/bin/env python
#coding=utf-8

from svgutils.compose import *
import matplotlib.pyplot as plt
import numpy as np

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)))
fig.savefig('cover.svg')

Figure("16cm", "6.5cm", 
    Panel(SVG('cover.svg')).scale(0.02),  # <---- difference to above
).save("composed.svg")

Still, I am wondering why the figure ends up so large. With figsize=(4,4) (inches), it should not be so much larger than 6.5cm (1inch=2.5cm)

michaeldeistler avatar Jun 16 '21 17:06 michaeldeistler

I can't comment on the scaling, and the size inconsistency, but since I also struggled for a while with this library and found some solution, I share it here:

After all, figure sizes do not really matter for vector graphics. Instead of using units, guessing scalings and figure sizes, I would recommend the following code for a figure with 2.5 times the width and 1.1 times the height of cover.svg (which is roughly what your code produces).:

svg = SVG('cover.svg', fix_mpl=True)
Figure(2.5*svg.width, 1.1*svg.height, Panel(svg)).save('composed.svg')

Leonard-Reuter avatar Jun 25 '21 10:06 Leonard-Reuter