如何在Python中导入SVG图片并添加标题与坐标轴标签?
解决Python中导入SVG图片并添加标题、坐标轴标签的问题
为什么plt.imread('./tune.svg')会报错?
plt.imread()仅支持PNG、JPG、BMP这类栅格图像格式,SVG是矢量图形,无法被该方法直接解析,因此会抛出格式不支持的错误。
可行解决方法
方法1:将SVG转为栅格图后读取(简单通用)
通过第三方工具把SVG转成PNG临时文件,再用matplotlib读取显示,适合快速实现需求:
- 先安装依赖:
pip install svglib pillow matplotlib
- 示例代码:
from svglib.svglib import svg2rlg from reportlab.graphics import renderPM from PIL import Image import numpy as np import matplotlib.pyplot as plt # 把SVG转成PNG临时文件 svg_drawing = svg2rlg("./tune.svg") renderPM.drawToFile(svg_drawing, "temp_svg.png", fmt="PNG") # 读取转好的图片并显示 img = Image.open("temp_svg.png") img_array = np.array(img) plt.figure(figsize=(8, 6)) plt.imshow(img_array) # 添加标题和坐标轴标签 plt.title("自定义SVG图片标题") plt.xlabel("X轴名称") plt.ylabel("Y轴名称") plt.axis('on') # 确保坐标轴显示 plt.show()
注意:这种方法会生成临时PNG文件,矢量图转为栅格图后放大可能会模糊。
方法2:直接导入SVG矢量路径(保留清晰度)
如果需要保留SVG的矢量特性(放大不失真),可以解析SVG的路径信息,直接在matplotlib中绘制:
- 安装依赖:
pip install svgpathtools matplotlib
- 示例代码:
import matplotlib.pyplot as plt from svgpathtools import svg2paths from matplotlib.path import Path from matplotlib.patches import PathPatch # 读取SVG的路径和属性 paths, attrs = svg2paths("./tune.svg") fig, ax = plt.subplots(figsize=(8, 6)) # 遍历所有路径并添加到坐标轴 for path, attr in zip(paths, attrs): vertices = [] codes = [] # 转换SVG路径段为matplotlib可识别的格式 for seg in path: if isinstance(seg, svgpathtools.Line): vertices.extend([(seg.start.real, seg.start.imag), (seg.end.real, seg.end.imag)]) codes.extend([Path.MOVETO, Path.LINETO]) elif isinstance(seg, svgpathtools.CubicBezier): vertices.extend([(seg.start.real, seg.start.imag), (seg.control1.real, seg.control1.imag), (seg.control2.real, seg.control2.imag), (seg.end.real, seg.end.imag)]) codes.extend([Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]) # 添加路径到画布 if vertices: patch = PathPatch(Path(vertices, codes), fill=attr.get('fill', 'none'), stroke=attr.get('stroke', 'black'), linewidth=float(attr.get('stroke-width', 1))) ax.add_patch(patch) # 调整坐标轴适配SVG大小 ax.autoscale() ax.set_aspect('equal', adjustable='box') # 添加标注 plt.title("矢量SVG图片标题") plt.xlabel("X轴标签") plt.ylabel("Y轴标签") plt.show()
注意:复杂SVG可能包含更多路径类型(如圆弧、二次贝塞尔),需要补充对应的转换逻辑。
方法3:用Pycairo直接渲染SVG(底层控制)
Pycairo对SVG支持较好,适合需要更精细控制渲染的场景:
- 安装依赖(部分系统需先安装系统级依赖,如Linux的
libcairo2-dev):
pip install pycairo matplotlib
- 示例代码:
import matplotlib.pyplot as plt import cairo import numpy as np # 创建matplotlib画布 fig, ax = plt.subplots(figsize=(8, 6)) ax.set_xlim(0, 800) ax.set_ylim(0, 600) # 初始化Cairo上下文 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 800, 600) ctx = cairo.Context(surface) # 读取并渲染SVG with open("./tune.svg", 'rb') as f: svg_data = f.read() try: svg_surface = cairo.SVGSurface.create_from_svg(ctx, svg_data, len(svg_data)) ctx.set_source_surface(svg_surface, 0, 0) ctx.paint() except Exception as e: print(f"渲染失败: {e}") # 转换Cairo表面为numpy数组并显示 buf = surface.get_data() img = np.ndarray(shape=(600, 800, 4), dtype=np.uint8, buffer=buf) img = img[:, :, :3] # 移除Alpha通道 ax.imshow(img) # 添加标注 plt.title("Cairo渲染SVG标题") plt.xlabel("X轴标签") plt.ylabel("Y轴标签") plt.show()
内容的提问来源于stack exchange,提问作者EngGu
相关产品推荐
相关产品推荐

