Scribus 中的 Python 脚本:制作饼图

425 位读者喜欢这篇文章。
Open innovation

Opensource.com

自 2001 年以来,Scribus 是一款强大的开源页面布局应用程序,由开源社区开发并依赖。 根据该项目的网站介绍,Scribus 是为 Linux、FreeBSD、PC-BSD、NetBSD、OpenBSD、Solaris 构建的,该程序提供 CMYK 颜色、专色、ICC 颜色管理和 PDF 创建。 该站点还吹捧该应用程序的高级功能,例如矢量绘图工具、通过导入/导出过滤器支持大量文件类型、模拟色盲或渲染 LaTeX 或 Lilypond 等标记语言。 即将推出的是执行复杂文本布局 (CTL) 以及使用 Open Type 字体中的高级功能的能力。 文件格式是 XML。 Scripter 是一个插件,用于在 Scribus 中启用 Python 语言脚本,是该软件包的一部分。

为了快速入门,我将构建一个饼图,这将让您对该程序的功能有一个不错的概述。 Scribus 内置了一些矢量绘图工具,但从数据列表到反映该数据的饼图的想法似乎是一项繁琐的工作——Scripter 的完美工作,它是 Scribus 的脚本插件。

经过一番调查,我决定研究可缩放矢量图形 (SVG) 作为创建图表的文件类型,特别是由于它有完善的文档记录,并且文件是 XML 中可读的。 Scribus 不仅可以导入 SVG,还可以在导入后对其进行编辑。

我不会在本文中展示整个脚本,但会重点介绍三个方面:SVG 结构、数学(注意:三角函数来了!)以及最后的 Scribus 部分。

您可以在 Scribus wiki 上的制作饼图条目中找到完整的脚本。那里有两个版本,这个特定版本位于页面 底部

那里还有更多关于脚本的解释。

SVG

如果我们想到一个饼图,数据向我们展示了饼的各个部分,或者说是一个圆的一部分,就像这个例子一样。

Scribus pie chart tutorial example

我们感兴趣的 SVG 命令是 path。 我希望这个单独的部分最终是这样的

<path d="M 200,200 l 150,0 a150,150 0 0,0 -275,-81 z" fill="red" stroke="black" stroke-width="0.5" stroke-linejoin="round" />
  • 绘制饼图部分的是 d= 后的表达式。
  • M 是我们的起点。(它大写,这意味着这是 X,Y 坐标的绝对位置,这是我们饼的中心。)
  • 从那里我们画一条线(小 l 表示与最后一个点的相对距离)到圆的边缘。
  • a 命令有点棘手。 这是为了绘制一个弧,第一个组件 150,150 指示我们圆的 x 和 y 半径,因为弧可能是椭圆的。
  • 接下来是 0,因为我们图形的坐标未从页面坐标旋转。
  • 下一个 0large-arc-flag。 如果您在圆上有 2 个点,您可以选择绕短路(角度小于 180°)或绕长路(大于 180°)。 因此,0 表示走短路。
  • 最后一个 0sweep-flag,告诉我们我们想逆时针绕这个圆走(1 会顺时针走)。
  • 最后,-275,-81 告诉我们端点相对于起点的坐标; 所以换句话说,我们需要知道该端点的相对笛卡尔坐标。 一旦我们知道了这一点,z 就只是说完成路径,连接回圆心。

你好,三角学!

Second Scribus example pie chart

在这个饼图中,我们可以看到我们可以创建一个假想的直角三角形,中心处的角度是我们部分对应的 360° 的百分比。 此外,如果我们想象这个部分在一个 X,Y 图中,顶点的坐标是三角形底边的宽度,三角形的高度,使用三角函数,

X = cos(angle) x radius
Y = sin(angle) x radius

我们拥有所有这些值,所以这就是我们之前示例中 -275,-81 的由来。

下一个部分的下一个数据点呢? 此时,我将做出一个行政决定。 为了使事情更简单,我将继续从原始起点计算,换句话说,就是我们假想图的 X 轴。

Third Scribus example pie chart

在此图中,我知道点 1、2 和 3,我只需要找到 4 的最快方法。 另一个决定是继续将各个部分绘制为闭合图形,因为这将有助于在 Scribus 中进行编辑,并且我们创建形状以填充颜色。

所以现在只是一个绕着饼图走的问题——我想我闻到了一种 Python 循环的味道,就是这样

for n in nvalues:
    arc = "0"
    seg = n/total * 360 + seg
    if ((n/total * 360) > 180):
        arc = "1"
    radseg = math.radians(seg)
    nextx = int(math.cos(radseg) * radius)
    nexty = int(math.sin(radseg) * radius)

    L.append('<path d="M '+str(startx)+','+str(starty) + ' l '+str(lastx)+','+str(-(lasty))+' a150,150 0 ' + arc + ',0 '+str(nextx - lastx)+','+str(-(nexty - lasty))+ ' z" \n')
    L.append('fill="'+colors[i]+'" stroke="' + bordercolor + '" stroke-width="0.5" stroke-linejoin="round" />\n')
    L.append('<rect x="375" y="'+ str(ykey) + '" width="40" height="30" fill="'+colors[i] + '" stroke="black" stroke-width="0.5"/>\n')
    ykey = ykey + 35
    lastx = nextx
    lasty = nexty
    i += 1
L.append('</svg>')
output = open(svgfile,'w')
output.writelines(L)
output.close()

变量 seg 是我们在绕饼图走时累积的弧。 接下来,我们进行计算,最终结果是将 SVG 代码行添加到 Python 列表中。 完成后,我们将其保存到文件中。

结果

Final Scribus pie chart example

 

对于所有番茄爱好者来说,此饼图显示了 2013 年(最新可用年份)排名前 10 位的番茄生产国的相对贡献。该脚本还做的是在侧面创建这些彩色填充的矩形和文本框,显示此饼图中描绘的总量。 稍后在 Scribus 中完成的修饰是在带有总数的框架中添加单位,稍微重新定位它,然后为颜色键添加文本框。

在 Scribus 中轻松对齐单词和矩形,在颜色列旁边创建一个细长的文本框,逐行键入单词。 当然,它们一开始不会对齐。 接下来,定位框架的顶部,使顶部单词与相应的颜色对齐,然后调整框架中的“固定行距”,直到底部单词(这里的墨西哥)与底部颜色的中间对齐。 行距可以调整到百分之一点。 完成。

将 SVG 加载到 Scribus 后,您会看到它在 Scribus 内部是一个组。 要编辑图形,您需要取消组合,之后所有线段和矩形都是单独的对象。 因为它是 SVG,您也可以在 Inkscape 中编辑。

Greg Pittman
格雷格是肯塔基州路易斯维尔的一位退休神经科医生,自 1960 年代起就对计算机和编程产生了浓厚的兴趣,从 Fortran IV 开始。 当 Linux 和开源软件出现时,它激发了人们学习更多知识的承诺,并最终做出了贡献。 他是 Scribus 团队的成员。

1 条评论

干得好!

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.