使用matplotlib保存为svg时如何设置miterlimit

时间:2016-09-08 00:14:44

标签: python svg matplotlib

在将matplotlib图保存到svg时,是否设置了miterlimit?我想以编程方式解决这个问题:https://bugs.launchpad.net/inkscape/+bug/1533058 而我不得不在" .svg"文本文件。

2 个答案:

答案 0 :(得分:1)

此参数定义为'stroke-miterlimit': '100000',并在backend_svg.py中进行了硬设置。 matplotlibrc中没有这样的参数,因此不太可能使用样式表进行自定义。

我使用以下代码来解决此问题:

def fixmiterlimit(svgdata, miterlimit = 10):
    # miterlimit variable sets the desired miterlimit
    mlfound = False
    svgout = ""
    for line in svgdata:
        if not mlfound:
             # searches the stroke-miterlimit within the current line and changes its value
             mlstring = re.subn(r'stroke-miterlimit:([0-9]+)', "stroke-miterlimit:" + str(miterlimit), line)
        if mlstring[1]: # use number of changes made to the line to check whether anything was found
            mlfound = True
            svgout += mlstring[0] + '\n'
        else:
            svgout += line + '\n'
    else:
        svgout += line + '\n'
return svgout

然后像这样调用它(使用此http://docs.confluent.io/3.0.1/installation.html#installation-yum的技巧):

import StringIO
...
imgdata = StringIO.StringIO() # initiate StringIO to write figure data to
# the same you would use to save your figure to svg, but instead of filename use StringIO object
plt.savefig(imgdata, format='svg',  dpi=90, bbox_inches='tight')
imgdata.seek(0)  # rewind the data
svg_dta = imgdata.buf  # this is svg data

svgoutdata = fixmiter(re.split(r'\n', svg_dta)) # pass as an array of lines
svgfh = open('figure1.svg', 'w')
svgfh.write(svgoutdata)
svgfh.close()

在将文件写入文件之前,代码基本上会更改SVG输出中的stroke-miterlimit参数。为我工作。

答案 1 :(得分:1)

感谢drYG提供了很好的答案和感谢问题。我有一个类似的问题,因为这个inkscape错误和缺乏一个简单的方法来更改matplotlib中的设置。但是,drYG的答案似乎不适用于python3。我更新了它并改变了似乎是一些拼写错误(无论python版本)。希望在我试图弥补我失去的东西时,它会节省一些时间!

def fixmiterlimit(svgdata, miterlimit = 10):
    # miterlimit variable sets the desired miterlimit
    mlfound = False
    svgout = ""
    for line in svgdata:
        if not mlfound:
            # searches the stroke-miterlimit within the current line and changes its value
            mlstring = re.subn(r'stroke-miterlimit:([0-9]+)', "stroke-miterlimit:" + str(miterlimit), line)
        #if mlstring[1]: # use number of changes made to the line to check whether anything was found
            #mlfound = True
            svgout += mlstring[0] + '\n'
        else:
            svgout += line + '\n'
    return svgout

import io, re
imgdata = io.StringIO() # initiate StringIO to write figure data to
# the same you would use to save your figure to svg, but instead of filename use StringIO object
plt.gca()
plt.savefig(imgdata, format='svg',  dpi=90, bbox_inches='tight')
imgdata.seek(0)  # rewind the data
svg_dta = imgdata.getvalue()  # this is svg data
svgoutdata = fixmiterlimit(re.split(r'\n', svg_dta)) # pass as an array of lines
svgfh = open('test.svg', 'w')
svgfh.write(svgoutdata)
svgfh.close()