一、pygal简介与核心概念
1.1 什么是矢量图
矢量图(SVG, Scalable Vector Graphics)是一种基于XML的二维图形格式,与位图不同,它使用数学公式描述图形,具有以下特性:
- 无限缩放:放大不会失真
- 文件体积小:适合网络传输
- 可编辑性:可通过代码或工具修改
- 交互性:支持JavaScript交互
1.2 pygal概述
pygal是一个Python矢量图表库,特点包括:
- 生成SVG格式图表
- 简洁易用的API
- 丰富的图表类型
- 高度可定制化
- 支持交互式图表
表1:pygal与其他图表库对比
特性 |
pygal |
Matplotlib |
Plotly |
Bokeh |
输出格式 |
SVG |
位图/SVG |
Web/交互 |
Web/交互 |
学习曲线 |
低 |
中 |
中 |
高 |
交互性 |
基础 |
有限 |
强 |
强 |
适用场景 |
简单报表 |
科学计算 |
网页嵌入 |
复杂仪表盘 |
二、pygal安装与基础使用
2.1 安装与配置
pip install pygal
可选依赖:
pip install lxml cssselect pygal_maps_world # 支持更多功能
2.2 基础图表创建
import pygal
# 创建柱状图
bar_chart = pygal.Bar()
bar_chart.title = '浏览器使用统计'
bar_chart.x_labels = ['Chrome', 'Firefox', 'Safari']
bar_chart.add('2023', [45.3, 30.2, 12.5])
bar_chart.render_to_file('browser_usage.svg')
效果:
2.3 图表渲染方式
pygal提供多种渲染方式:
- render_to_file(filename):保存为SVG文件
- render_to_png(filename):保存为PNG(需安装lxml)
- render_data_uri():生成Base64编码的SVG数据URI
- render(is_unicode=True):返回SVG字符串
三、pygal核心图表类型详解
3.1 基本图表类型
3.1.1 柱状图(Bar)
class pygal.Bar( title=None, # 图表标题 x_labels=None, # X轴标签 y_labels=None, # Y轴标签 show_legend=True, # 是否显示图例 legend_at_bottom=False, # 图例是否在底部 # 更多参数... )
应用案例:销售数据对比
def create_sales_comparison():
'''生成季度销售对比柱状图'''
bar = pygal.Bar(
title='2023年季度销售对比',
x_labels=['Q1', 'Q2', 'Q3', 'Q4'],
show_legend=True,
legend_at_bottom=True
)
bar.add('北京', [125, 132, 148, 189])
bar.add('上海', [110, 145, 162, 178])
bar.add('广州', [98, 112, 135, 156])
bar.render_to_file('quarterly_sales.svg')
效果:
3.1.2 折线图(Line)
class pygal.Line( fill=False, # 是否填充区域 interpolate='cubic', # 插值方式 stroke_style=None, # 线条样式 # 更多参数... )
应用案例:温度变化趋势
def create_temperature_chart():
'''生成城市温度变化折线图'''
line_chart = pygal.Line(
title='2023年主要城市月平均温度(℃)',
x_labels=map(str, range(1, 13)),
interpolate='cubic',
fill=True
)
line_chart.add('北京', [-4, -1, 7, 15, 22, 26, 28, 26, 21, 14, 5, -2])
line_chart.add('上海', [4, 6, 10, 16, 21, 25, 29, 29, 25, 19, 13, 7])
line_chart.render_to_file('temperature.svg')
效果:
3.2 高级图表类型
3.2.1 饼图(Pie)
class pygal.Pie( inner_radius=0, # 内半径(创建环形图) half_pie=False, # 是否显示半圆 # 更多参数... )
应用案例:市场份额分布
def create_market_share_chart():
'''生成市场份额饼图'''
pie_chart = pygal.Pie(
title='2023年智能手机市场份额',
inner_radius=0.4, # 创建环形图
print_values=True
)
pie_chart.add('Apple', 28.1)
pie_chart.add('Samsung', 22.8)
pie_chart.add('Xiaomi', 12.7)
pie_chart.add('OPPO', 8.6)
pie_chart.add('其他', 27.8)
pie_chart.render_to_file('market_share.svg')
效果:
3.2.2 雷达图(Radar)
class pygal.Radar( show_dots=True, # 是否显示数据点 fill=True, # 是否填充区域 # 更多参数... )
应用案例:技能评估
def create_skill_radar():
'''生成技能评估雷达图'''
radar_chart = pygal.Radar(
title='技术能力评估',
fill=True,
show_dots=True
)
radar_chart.x_labels = ['Python', 'SQL', 'Linux', 'Docker', '机器学习']
radar_chart.add('张三', [9, 7, 6, 8, 7])
radar_chart.add('李四', [7, 8, 5, 6, 9])
radar_chart.render_to_file('skills.svg')
效果:
3.2.3 金字塔图(Pyramid)
class pygal.Pyramid( reverse=False, # 是否反转金字塔 # 其他参数... )
应用案例:人口年龄结构
def create_population_pyramid():
'''生成人口金字塔图'''
pyramid = pygal.Pyramid(
title='2023年人口年龄结构',
legend_at_bottom=True
)
pyramid.add('男性', [4.2, 4.0, 3.8, 3.5, 3.0, 2.5, 1.8, 1.2, 0.7])
pyramid.add('女性', [4.0, 3.9, 3.7, 3.4, 3.2, 2.8, 2.2, 1.5, 1.0])
pyramid.x_labels = ['0-9', '10-19', '20-29', '30-39',
'40-49', '50-59', '60-69', '70-79', '80+']
pyramid.render_to_file('population.svg')
效果:
3.2.4 散点图(XY)
class pygal.XY( stroke=False, # 是否连接点 # 其他参数... )
应用案例:身高体重分布
def create_scatter_plot():
'''生成身高体重散点图'''
xy_chart = pygal.XY(
title='身高体重分布',
stroke=False,
show_legend=False
)
# 模拟数据
import random
data = [(random.gauss(170, 10), random.gauss(65, 8)) for _ in range(100)]
xy_chart.add('成年人', data)
xy_chart.render_to_file('height_weight.svg')
效果:
3.2.5 仪表盘图(Gauge/SolidGauge)
class pygal.SolidGauge( half_pie=True, # 是否显示半圆 inner_radius=0.70, # 内半径 # 其他参数... )
应用案例:系统监控仪表盘
def create_system_gauge():
'''生成系统监控仪表盘'''
gauge = pygal.SolidGauge(
half_pie=True,
inner_radius=0.70,
show_legend=False
)
# 添加多个指标
gauge.add('CPU', [{'value': 65, 'max_value': 100}])
gauge.add('内存', [{'value': 45, 'max_value': 100}])
gauge.add('磁盘', [{'value': 78, 'max_value': 100}])
gauge.render_to_file('system_monitor.svg')
效果:
3.2.6 树状图(Treemap)
class pygal.Treemap( truncate_legend=-1, # 图例截断长度 # 其他参数... )
应用案例:文件系统分析
def create_filesystem_map():
'''生成文件系统树状图'''
treemap = pygal.Treemap(
title='磁盘空间占用分析',
truncate_legend=20
)
treemap.add('系统', [
{'value': 45, 'label': 'Windows'},
{'value': 25, 'label': 'Program Files'},
{'value': 15, 'label': 'Users'}
])
treemap.add('数据', [
{'value': 30, 'label': '数据库'},
{'value': 20, 'label': '文档'},
{'value': 10, 'label': '多媒体'}
])
treemap.render_to_file('filesystem.svg')
效果:
3.3 其他图表类型
3.3.1 点图(Dot)
class pygal.Dot( dots_size=5, # 点大小 # 其他参数... )
应用案例
dot_chart = pygal.Dot(x_label_rotation=30)
dot_chart.title = 'V8 benchmark results'
dot_chart.x_labels = ['Richards', 'DeltaBlue', 'Crypto', 'RayTrace', 'EarleyBoyer', 'RegExp', 'Splay', 'NavierStokes']
dot_chart.add('Chrome', [6395, 8212, 7520, 7218, 12464, 1660, 2123, 8607])
dot_chart.add('Firefox', [7473, 8099, 11700, 2651, 6361, 1044, 3797, 9450])
dot_chart.add('Opera', [3472, 2933, 4203, 5229, 5810, 1828, 9013, 4669])

dot_chart.add('IE', [43, 41, 59, 79, 144, 136, 34, 102])
dot_chart.render()
效果:
3.3.2 漏斗图(Funnel)
class pygal.Funnel( zero=0, # 零点位置 # 其他参数... )
应用案例
funnel_chart = pygal.Funnel()
funnel_chart.title = 'V8 benchmark results'
funnel_chart.x_labels = ['Richards', 'DeltaBlue', 'Crypto', 'RayTrace', 'EarleyBoyer', 'RegExp', 'Splay', 'NavierStokes']
funnel_chart.add('Opera', [3472, 2933, 4203, 5229, 5810, 1828, 9013, 4669])
funnel_chart.add('Firefox', [7473, 8099, 11700, 2651, 6361, 1044, 3797, 9450])
funnel_chart.add('Chrome', [6395, 8212, 7520, 7218, 12464, 1660, 2123, 8607])
funnel_chart.render()
效果:
3.3.3 箱线图(Box)
class pygal.Box( box_mode='tukey', # 计算方式:'tukey'或'1.5IQR' # 其他参数... )
应用案例
box_plot = pygal.Box()
box_plot.title = 'V8 benchmark results'
box_plot.add('Chrome', [6395, 8212, 7520, 7218, 12464, 1660, 2123, 8607])
box_plot.add('Firefox', [7473, 8099, 11700, 2651, 6361, 1044, 3797, 9450])
box_plot.add('Opera', [3472, 2933, 4203, 5229, 5810, 1828, 9013, 4669])
box_plot.add('IE', [43, 41, 59, 79, 144, 136, 34, 102])
box_plot.render()
效果:
3.3.4 轨距图(Gauge)
class pygal.Gauge( human_readable=True, # 其他参数... )
应用案例
gauge_chart = pygal.Gauge(human_readable=True)
gauge_chart.title = 'DeltaBlue V8 benchmark results'
gauge_chart.range = [0, 10000]
gauge_chart.add('Chrome', 8212)
gauge_chart.add('Firefox', 8099)
gauge_chart.add('Opera', 2933)
gauge_chart.add('IE', 41)
gauge_chart.render()
效果:
表2:pygal图表类型适用场景
图表类型 |
适用场景 |
数据要求 |
柱状图(Bar) |
比较不同类别数据 |
类别+数值 |
折线图(Line) |
展示趋势变化 |
时间/顺序+数值 |
饼图(Pie) |
展示占比关系 |
各部分占总和的比例 |
雷达图(Radar) |
多维数据比较 |
多个维度的数值 |
散点图(XY) |
展示相关性或分布 |
成对的数值数据 |
箱线图(Box) |
展示数据分布统计 |
需要计算四分位数 |
仪表盘(Gauge) |
展示进度或指标 |
当前值+最大值 |
树状图(Treemap) |
层级数据可视化 |
层级结构+数值 |
热图(Heatmap) |
二维密度可视化 |
两个分类轴+强度值 |
四、pygal高级特性与定制化
4.1 样式定制
pygal提供多种内置样式,也可自定义样式:
from pygal.style import Style # 自定义样式 custom_style = Style( background='white', plot_background='#f0f0f0', foreground='rgba(0, 0, 0, 0.9)', opacity='.6', colors=('#E853A0', '#E8537A', '#E95355', '#E87653', '#E89B53') ) pie_chart = pygal.Pie(style=custom_style)
表3:pygal内置样式
样式名称 |
描述 |
适用场景 |
DefaultStyle |
默认样式 |
通用 |
DarkStyle |
暗色主题 |
深色背景 |
LightStyle |
浅色主题 |
打印文档 |
NeonStyle |
霓虹色彩 |
吸引注意力 |
RedBlueStyle |
红蓝配色 |
对比数据 |
4.2 交互功能
pygal支持基本的交互功能:
line_chart = pygal.Line(
tooltip_fancy_mode=False, # 简化提示框
show_x_guides=True, # 显示X轴参考线
show_y_guides=True, # 显示Y轴参考线
js=[] # 自定义JavaScript
)
应用案例:添加自定义提示
bar_chart = pygal.Bar( tooltip_formatter=lambda x: f'销量: {x}万件' )
4.3 动态图表生成
pygal可与Web框架集成,动态生成图表:
from flask import Flask, Response
app = Flask(__name__)
@app.route('/chart')
def render_chart():
chart = pygal.Line(title='动态图表')
chart.add('数据', [1, 3, 5, 2, 4])
return Response(
chart.render(),
content_type='image/svg+xml'
)
五、pygal应用
5.1 数据可视化报表生成
def generate_sales_report(data): ''' 生成销售报表 :param data: 包含销售数据的字典 :return: 生成SVG文件路径列表 ''' # 1. 月销售额趋势图 line_chart = pygal.Line( title='2023年月销售额趋势', x_labels=['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], show_x_guides=True ) line_chart.add('销售额(万元)', data['monthly_sales']) # 2. 产品类别占比 pie_chart = pygal.Pie( title='产品类别占比', inner_radius=0.4, print_values=True ) for category, value in data['category_dist'].items(): pie_chart.add(category, value) # 保存文件 files = [ 'sales_trend.svg', 'category_dist.svg' ] line_chart.render_to_file(files[0]) pie_chart.render_to_file(files[1]) return files
5.2 仪表盘集成
def create_dashboard(metrics):
'''
创建系统监控仪表盘
:param metrics: 系统指标字典
:return: SVG字符串
'''
gauge = pygal.SolidGauge(
half_pie=True,
inner_radius=0.70,
show_legend=False
)
# CPU使用率
gauge.add('CPU', [
{'value': metrics['cpu'], 'max_value': 100},
], formatter=lambda x: f'{x}%')
# 内存使用率
gauge.add('内存', [
{'value': metrics['memory'], 'max_value': 100},
])
# 磁盘使用率
gauge.add('磁盘', [
{'value': metrics['disk'], 'max_value': 100},
])
return gauge.render(is_unicode=True)
5.3 大数据集处理技巧
对于大数据集,pygal提供了一些优化选项:
large_chart = pygal.Line( x_labels_major_every=5, # 每5个标签显示一个主标签 show_minor_x_labels=False, # 不显示次要标签 truncate_label=15, # 标签截断长度 width=1200, # 增加画布宽度 explicit_size=True # 明确指定尺寸 )
六、pygal扩展应用
6.1 地图图表
安装地图扩展:
pip install pygal_maps_world
世界地图示例:
worldmap_chart = pygal.maps.world.World() worldmap_chart.title = '全球用户分布' worldmap_chart.add('用户数', { 'cn': 100000, 'us': 80000, 'jp': 50000, 'in': 75000, 'br': 45000 }) worldmap_chart.render_to_file('world_users.svg')
效果:
6.2 与Pandas集成
import pandas as pd
# 从Pandas DataFrame创建图表
def create_from_dataframe(df):
'''
从DataFrame生成图表
:param df: Pandas DataFrame
:return: pygal图表对象
'''
line_chart = pygal.Line()
line_chart.title = '股票价格趋势'
line_chart.x_labels = df['date'].dt.strftime('%Y-%m-%d')
for column in df.columns[1:]:
line_chart.add(column, df[column])
return line_chart
6.3 3D图表效果
虽然pygal本身是2D库,但可以通过视觉技巧模拟3D效果:
bar_chart = pygal.Bar( style=pygal.style.LightStyle( value_colors=('white',), value_font_family='googlefont:Raleway' ), depth=0.5, # 深度效果 perspective=0.2 # 透视效果 )
七、性能优化
7.1 性能优化技巧
- 减少数据点:对于大数据集,适当采样
- 简化样式:避免复杂渐变和阴影
- 禁用不需要的功能:如动画效果
- 预渲染静态图表:避免每次请求都重新生成
7.2 实践应用
- 图表选择原则:
- 趋势分析 → 折线图
- 对比分析 → 柱状图
- 占比分析 → 饼图/环形图
- 分布分析 → 散点图/箱线图
- 配色方案:
- 使用不超过7种颜色
- 重要数据使用高对比色
- 考虑色盲友好配色
- 标签处理:
- 避免标签重叠
- 过长的标签使用缩写
- 重要数据直接标注在图表上
八、学习路线图
8.1 学习路径
8.2 推荐资源
- 官方文档:pygal官方文档 (http://www./)
- GitHub仓库:pygal GitHub (https://github.com/Kozea/pygal)
- 扩展库: pygal_maps_world:世界地图 pygal_maps_fr:法国地图 pygal_maps_ch:瑞士地图
- 相关书籍: 《Python数据可视化》 《数据可视化实战》
九、总结与展望
9.1 技术总结
pygal作为Python矢量图表库,具有以下优势:
- 简单易用,适合快速生成美观的SVG图表
- 丰富的图表类型满足常见需求
- 高度可定制化的样式和交互
- 轻量级,适合Web应用集成
9.2 展望
- 更多图表类型:如桑基图、热力图等
- 增强交互性:更丰富的JavaScript API
- 更好的移动端支持:响应式图表设计
- 与新兴技术集成:如JupyterLab、Voila等
9.3 建议
对于Python开发者:
- 需要简单快速生成矢量图 → 选择pygal
- 需要复杂科学可视化 → 考虑Matplotlib
- 需要丰富交互式图表 → 考虑Plotly或Bokeh
pygal在报表生成、简单数据展示和教育领域有着独特的优势,可以为Python数据可视化工作带来极大的便捷性。
持续更新Python编程学习日志与技巧,敬请关注!
#编程# #python# #在头条记录我的2025#