I have a big vector graphic in SVG format and I want to plot into it using matplotlib. To do so I create the matplotlib plot, store it as SVG and then merge the files. However, the coordinates that matplotlib uses do not match the coordinates of my main SVG file.
To find the location of the object I want to plot over, I use its id
and translate
property (recursively, if necessary), e.g.
If I want to plot to the location of "X" in
<?xml version="1.0" encoding="UTF-8"?>
<svg width="2283px" height="1252px" viewBox="0 0 300 300" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g xmlns="http://www.w3.org/2000/svg" id="X"
transform="translate(10.0, 20.0)" fill-rule="nonzero">
<circle id="circle" stroke="#FF5252" stroke-width="2" fill="#FFFFFF" cx="4" cy="4" r="4"/>
</g>
</svg>
I plot to (10, 20) using the following code:
import matplotlib as mpl
import matplotlib.pyplot as plt
# set the backend to SVG,
# according to https://stackoverflow.com/questions/70759115/text-position-changes-when-a-matplotlib-figure-is-saved-in-svg
mpl.use('svg')
fig, ax = plt.subplots(1, 1, squeeze=True)
plt.axis('off')
# print to the location of "X"
ax.scatter([10], [20])
# needs to be done according to
# https://stackoverflow.com/questions/24525111/how-can-i-get-the-output-of-a-matplotlib-plot-as-an-svg
# otherwise the produced output is not in a visible bound
plt.gca().set_position([0, 0, 1, 1])
plt.savefig('/tmp/test.svg', backend='svg', format='svg', transparent=True)
But the output has an offset and is scaled.
Result:
Red circle is from the original SVG, blue dot is from matplotlib.
Note that I put the SVG object "X" into the body of "/tmp/test.svg"