Python学习笔记#11 - pygal绘制图表字体大小设置

《Python编程:从入门到实践》17.2.1节中绘制条形图“GitHub上受欢迎程度最高的Python项目”,代码如下:

#coding=gbk
import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS

# 执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(url)
print("Status code:", r.status_code)

# 将API响应存储在一个变量中
response_dict = r.json()
print("Total repositories:", response_dict['total_count'])

# 探索有关仓库的信息
repo_dicts = response_dict['items']
#print("Repositories returned:", len(repo_dicts))

names, stars = [], []
for repo_dict in repo_dicts:
    names.append(repo_dict['name'])
    stars.append(repo_dict['stargazers_count'])

# 可视化
my_style = LS('#333366', base_style=LCS)

my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_legend = False

#以下三句设置字体的语句有问题
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18

my_config.truncate_label = 15 # 将标签截断为15个字符
                              # 如果将鼠标指向被截断的标签,将显示完整标签
my_config.show_y_guides = False # 隐藏图表中的水平线(y guide lines)
my_config.width = 1000 # 图标宽度,默认800
chart = pygal.Bar(my_config, style=my_style)
#chart.config.style.title_font_size = 24
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names
chart.add('', stars)
chart.render_to_file('python_repos.svg')

其中有关于字体设置的三行语句

my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18

书中对此的解释为

设置了图表标题、副标签和主标签的字体大小。在这个
图表中,副标签是 x 轴上的项目名以及 y 轴上的大部分数字。主标签是 y 轴上为5000整数倍的刻度;这些标签应更大,以与副标签区分开来。

看得一头雾水,label_font_size和major_label_font_size分别对应副标签和主标签的字体大小?遂查阅pygal文档,想看看官方对label_font_size和major_label_font_size的解释。

首先查看config类
class pygal.config.Config(**kwargs)

却发现其中并没有title_font_size、label_font_size、major_label_font_size这几个属性。

再检索title_font_size,发现这个属性出现在style类中,于是查看style类
class pygal.style.Style(**kwargs)

发现其包含有title_font_size、label_font_size、major_label_font_size三个属性。而config类中包含一个名为style的style类属性。

注释掉my_config.title_font_size = 24,绘制出来的图标也是一样的,说明那这句代码没有起作用。

因为config类中包含属性style,尝试将my_config.title_font_size = 24改为my_config.style.title_font_size = 24,绘制出的柱状图标题字体大小未发生改变,逐语句调试发现title_font_size默认值为16。

my_config.title_font_size = 24注释掉,在chart = pygal.Bar(my_config, style=my_style)后面添加一行代码chart.config.style.title_font_size = 24,成功改变了标题字体大小。
title_font_size = 16
title_font_size = 24
可是my_config.style.title_font_size = 24明明修改了config类实例my_config中的属性style中的属性title_font_size,为什么在建立一个Bar实例chart时chart = pygal.Bar(my_config, style=my_style),没能将这个参数传递给柱状图呢?

通过逐语句调试发现,在建立一个Bar实例时,先会进行BaseGraph类的初始化(代码如下),首先传递config参数,然后传递余下的关键词参数。

class BaseGraph(object):

    """Chart internal behaviour related functions"""

    _adapters = []

    def __init__(self, config=None, **kwargs):
        """Config preparation and various initialization"""
        if config:
            if isinstance(config, type):
                config = config()
            else:
                config = config.copy()
        else:
            config = Config()

        config(**kwargs)
        self.config = config
        self.state = None
        self.uuid = str(uuid4())
        self.raw_series = []
        self.xml_filters = []

my_config确实传递给了BaseGraph类的config,包括my_config的style属性也传递给了config的style属性,此时title_font_size为24,问题发生在发生在**kwargs的传递,**kwargs传递完成后,title_font_size变为默认值16。**kwargs只收集了一个关键词为style的实参my_style。而在上述代码中可以看到,**kwargs收集的关键词参数,都传递给了BaseGraph类的config。

这时我才意识到,my_style其实是一个style类,其中也包含属性title_font_size,在创建my_style时,只是传递了位置实参color,和关键词实参base_style,并没有修改其中的title_font_size,所以my_style的属性title_font_size为默认值16,在创建Bar实例时,通过关键词实参传递给了chart。明白了这其中的参数传递过程后,就知道应该怎样有效地修改title_font_size了。

除了上面提及的一种方法外,还可以直接修改my_style中的title_font_size:
my_style.title_font_size = 24

或者在创建style实例my_style时,就通过关键词实参传递title_font_size的值:
my_style = LS('#333366', base_style=LCS, title_font_size=24)

既然config实例my_config中包含属性style,也可以修改my_config中的style属性,省去style实例my_style的创建和传递:

my_config.style.title_font_size = 24
my_config.style = LS('#333366', base_style=LCS)
chart = pygal.Bar(my_config)

这时我想到,作者不会犯下这么低级的错误,那三行修改字体大小的代码在彼时应该是有效的,仔细对比发现,使用此代码绘制出来的柱状图和书中所示柱状图有所不同:
书中所示柱状图:
书中所示柱状图
实际绘制柱状图:
实际绘制柱状图
如此看来很可能是pygal发生了变更,遂查阅pygal的变更日志,果然发现pygal 2.0.0发生了如下变动:
pygal 2.0.0 Changelog

猜你喜欢

转载自blog.csdn.net/weixin_43091089/article/details/99792892
今日推荐