Small fix for SVG backend

Hi,
I tried to use matplotlib.rcParams['svg.embed_char_paths'] = False in
order to have editable text in exported SVG, but there was an encoding
issue and the file data could not be written (traceback appended).

Therefore I exchanged the XML character escaping from sax in
backend_svg.py with python's native XML escape capability (see appended
diff), and voilà it works!

The conversion of mathtext to SVG is still not so nice because specific
fonts (cmmi10, cmr10, cmsy10) are used that encode mathematic symbols
with other unrelated characters. The formula display will totally break
if these fonts aren't installed, and editing is a pain. It would
therefore be great if unicode characters were used so that the correct
display is not so much dependent on those specific fonts. Would this
introduce other problems and where would be the best point to make that
change?

Greetings,
Dieter

traceback.txt (2.71 KB)

backend_svg.diff (598 Bytes)

Unfortunately, this isn't a complete solution. The purpose of the "escape_xml_chars" function is to escape characters that have special meaning in XML, e.g. "&" -> "&amp;", "<" -> "&lt;" etc. The "xmlcharrefreplace" option on encode() does not do that.

I am surprised that you got this traceback, as the SVG is output using a UTF-8 EncodedFile object, which should be able to handle any unicode characters you throw at it. Can you provide a short, standalone example that reproduces the error, and some information about your platform, so I can examine further?

As for your suggestion to encode mathematical characters as unicode, unfortunately that would only partially. In order to layout the mathematical expressions, we must have the same font available at generation and rendering time to know the size of the characters and therefore how to place them next to each other correctly. That said, if you use the STIX fonts (set "mathtext.fontset" to "STIX"), those do use a Unicode-based encoding rather than the arbitrary one used by the Bakoma Computer Modern fonts. Of course, generating a math expression using the STIX fonts and rendering it using a different Unicode math font is not guaranteed to work well -- you are almost certain to get overlapping or misplaced glyphs.

Mike

Hi Mike,
the error only occurs if the output file is specified as a file(-like)
object instead of a file name. This is necessary for me in order to add
a matplotlib-generated file to a tar archive via a safe temporary file.

Greetings,
Dieter

svg-export (454 Bytes)

What platform are you on? It "works for me" on Fedora 14, RHEL 5 and Cygwin.

Mike

···

On 12/16/2010 10:59 AM, Dieter Weber wrote:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib
import matplotlib.pyplot as pp
import tempfile
import cStringIO as StringIO

matplotlib.rcParams['svg.embed_char_paths'] = False

pp.plot([1, 2], [1, 2], label=u"äöü")
pp.legend()

# works
pp.savefig('test.svg')

# breaks
with open('test2.svg', 'wb') as ofile:
     pp.savefig(ofile, format='svg')

# breaks
ostr = StringIO.StringIO()
pp.savefig(ostr, format='svg')

Hi Mike,
sorry, I forgot my platform in my last mail!

I am running Ubuntu 10.04.1 LTS x86_64

Python: 2.6.5, Ubuntu
matplotlib: svn trunk, revision 8841

All other dependencies of matplotlib are installed as "normal" packages
of the distribution. Versions can be found here:
http://packages.ubuntu.com/lucid/python/

Would you like more information or should I run more tests?

Greetings,
Dieter

···

Am Donnerstag, den 16.12.2010, 15:40 -0500 schrieb Michael Droettboom:

What platform are you on? It "works for me" on Fedora 14, RHEL 5 and
Cygwin.

Mike

On 12/16/2010 10:59 AM, Dieter Weber wrote:
> #!/usr/bin/env python
> # -*- coding: utf-8 -*-
> import matplotlib
> import matplotlib.pyplot as pp
> import tempfile
> import cStringIO as StringIO
>
> matplotlib.rcParams['svg.embed_char_paths'] = False
>
> pp.plot([1, 2], [1, 2], label=u"äöü")
> pp.legend()
>
> # works
> pp.savefig('test.svg')
>
> # breaks
> with open('test2.svg', 'wb') as ofile:
> pp.savefig(ofile, format='svg')
>
> # breaks
> ostr = StringIO.StringIO()
> pp.savefig(ostr, format='svg')

Can you try applying the attached patch and let me know if it resolves the problem for you?

Mike

encoding.diff (1.37 KB)

···

On 12/17/2010 04:22 AM, Dieter Weber wrote:

Hi Mike,
sorry, I forgot my platform in my last mail!

I am running Ubuntu 10.04.1 LTS x86_64

Python: 2.6.5, Ubuntu
matplotlib: svn trunk, revision 8841

All other dependencies of matplotlib are installed as "normal" packages
of the distribution. Versions can be found here:
http://packages.ubuntu.com/lucid/python/

Would you like more information or should I run more tests?

Greetings,
Dieter

Am Donnerstag, den 16.12.2010, 15:40 -0500 schrieb Michael Droettboom:

What platform are you on? It "works for me" on Fedora 14, RHEL 5 and
Cygwin.

Mike

On 12/16/2010 10:59 AM, Dieter Weber wrote:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib
import matplotlib.pyplot as pp
import tempfile
import cStringIO as StringIO

matplotlib.rcParams['svg.embed_char_paths'] = False

pp.plot([1, 2], [1, 2], label=u"äöü")
pp.legend()

# works
pp.savefig('test.svg')

# breaks
with open('test2.svg', 'wb') as ofile:
      pp.savefig(ofile, format='svg')

# breaks
ostr = StringIO.StringIO()
pp.savefig(ostr, format='svg')

Hi Mike,
the patch resolved my problem. Thanks a lot!

Greetings,
Dieter