IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python-pyecharts绘图-坐标轴标签格式化formatter+刻度调整+批量输出为pdf -> 正文阅读

[Python知识库]python-pyecharts绘图-坐标轴标签格式化formatter+刻度调整+批量输出为pdf

问题描述

昨天一直在搞pyecharts绘图和输出,网上搜了不少,坑太多了。。。最终我绘图的结果如下:
在这里插入图片描述
遇到的难点:(下面会逐一给出解法!完整代码涉及隐私,恕不提供!有问题请留言讨论

  1. x轴和y轴的名称需要修改位置、字体、颜色
  2. 更改线条颜色
  3. x轴横坐标最小值与原点重合
  4. y轴的刻度需要自定义+控制格式
  5. x轴和y轴的副刻度需要自定义
  6. 曲线顶点处需要放置文字
  7. 需要输出pdf

环境

win10 + Python 3.9.12 + pyecharts 1.9.1 + snapshot_phantomjs 0.0.3

解决方案

以下直接略过数据准备阶段。已知 x_list是x的值列表,pts_list是y的值列表。

整体结构

代码的整体结构如下:

from pyecharts.charts import Line, Grid
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode

def draw(file_name):
	# 准备数据 x_list:list[str], pts_list:list[float]
	# x_list2 = [""] * (len(x_list)-1)
	# 绘制折线
    line = (
    	# 整体初始化,如图像宽、高,背景颜色等
        Line(init_opts=opts.InitOpts(height="600px", bg_color='rgb(255, 255, 255)')) 
            # x轴数据
            .add_xaxis(x_list)
            # y的数据、线的颜色、点的形状等
            .add_yaxis(pts_list)
            .set_global_opts(
            	# x轴上的文字,如x轴名称、范围、对齐方式、与轴的距离、字体颜色等
                xaxis_opts=opts.AxisOpts(),
                # y轴同理
                yaxis_opts=opts.AxisOpts(),
                # 设置图上的文字附注
                graphic_opts=[
                    opts.GraphicText(
                    	# 设置位置、旋转方向等
                        graphic_item=opts.GraphicItem(),
                        # 设置字号、颜色、字体、内容等
                        graphic_textstyle_opts=opts.GraphicTextStyleOpts(),
                    ),
                ],
            )
    )
    # 绘制副刻度:没有放数值,只是为了画刻度
    line2 = (Line()
           .add_xaxis(x_list2)
           .set_global_opts(
                    xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts()),
                    yaxis_opts=opts.AxisOpts(),
                    )
    )
    # 这里为了将两部分组合起来
    grid = Grid()
    # pos_left是左侧的边距,也就是将图向右移动一些。同理还有pos_left pos_top等
    grid.add(line, grid_opts=opts.GridOpts(pos_left='12%'))
    grid.add(line2, grid_opts=opts.GridOpts(pos_left='12%'))
    # 保存为html文件
    #grid.render("html/" + file_name + ".html")
    # 
    # 也可以用phantomjs另存为图像或pdf,后文会介绍
    # from pyecharts.render import  make_snapshot
    # from snapshot_phantomjs import snapshot
    #make_snapshot(snapshot, grid.render(), "pdf/" + file_name + ".pdf")
    #make_snapshot(snapshot, grid.render(), "pdf/" + file_name + ".png")

x轴和y轴的名称需要修改位置、字体、颜色

下面以x轴举例。y轴是差不多的。

.set_global_opts(
    xaxis_opts=opts.AxisOpts(
    					 # 坐标轴名称
    					 name="xxx",
    					 # 最小值
    					 min_=x_list[0],
    					 # 最大值
    					 max_=x_list[-1],
    					 # 是否将最小值与原点重合。如果是True的话,最小值跟原点之间会有距离
                         boundary_gap=False, 
                         # 水平对齐。y轴的应该写middle,就是竖着居中了
                         name_location='center',
                         # 名称与轴之间的距离 
                         name_gap=30, 
                         # 坐标轴名字的格式
                         name_textstyle_opts=opts.TextStyleOpts(
                             color='navy',
                             font_family='Courier New',
                             font_size=15,
                            ),
                         # 刻度值的格式。此处是主刻度,interval表示隔x个显示一个刻度值
                         axislabel_opts=opts.LabelOpts(
                             color='navy',
                             font_size=15,
                             font_family='Courier New',
                             interval=299,
                         ),

更改线条颜色

.add_yaxis(y_axis=pts_list,series_name="",
           is_symbol_show=False, # 去掉线上的圆圈
           linestyle_opts=opts.LineStyleOpts(color="red", width=0.7), # 设置线条格式
           label_opts=opts.LabelOpts(is_show=False),
           )

x轴横坐标最小值与原点重合

boundary_gap=False, 

参见上上节。

y轴的刻度需要自定义+控制格式

# 刻度值
axislabel_opts=opts.LabelOpts(
    # 文本格式控制
    color='navy',
    font_size=15,
    font_family='Courier New',
    #formatter="{value}E+00" + postfix,
    # postfix是一个str类型变量
    formatter=JsCode(
        '''
        function(value){
            if (value == '0') {
                return '0.0E+000';
            } else {
                return value + 'E+00' + 'TAIL';
            }
        }'''.replace('TAIL', postfix)
    ),
),

这里要说明一下formatter。JsCode实际是一段字符串,value表示的是某个刻度的值,是字符串类型,可以用console.log打出来看看。
怎么传递变量进去,我真的没搞懂,但是,用另一个常量代替待传递变量,然后replace掉,是可以实现我要的效果的。

x轴和y轴的副刻度需要自定义

因为line1的坐标轴刻度是跟着数据走的,为了多加一套副刻度,所以我另外写了一个line2,只用来控制副刻度,然后再把line1和line2叠加起来。这里副刻度需要控制的是interval。

    line2 = (Line()
           .add_xaxis(x_list2)
           .set_global_opts(
                    ...
                    yaxis_opts=opts.AxisOpts(
                                    max_=max_y,
                                    min_=0.0,
                                    # y_step是主刻度的interval值
                                    interval=y_step/ 4,
                                    # 只显示刻度,不显示标签
                                    axislabel_opts=opts.LabelOpts(
                                         color='transparent',
                                         font_size=15,
                                         font_family='Courier New',
                                     ),
                                    # 设置刻度颜色
                                    axisline_opts=opts.AxisLineOpts(linestyle_opts=opts.LineStyleOpts(color='navy')),
                                    ),
                    )
           )

曲线顶点处需要放置文字

graphic_opts=[
    opts.GraphicText(
    	# 修改位置和旋转角度。注意rotation用的是弧度,不是角度
        graphic_item=opts.GraphicItem(position=(455,40),rotation=0.5*pi),
        graphic_textstyle_opts=opts.GraphicTextStyleOpts(
            text=str(num), # 这个num是我自定义的变量
            font="13 Courier New", # 字号和字体
            # 文字颜色
            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(fill='navy')
        ),
    ),
],

输出pdf

先上结论:使用pyecharts推荐的phantomjs是最好的。
不过,这种方法生成的pdf只有图像,没办法调节边距、图纸方向和大小等,一种解决方案是使用毒霸PDF转换器-图片转PDF,可以批量转换(测试时,200个png转pdf在3分钟以内完成)。当然,也有很多工具可以使用。
在这里插入图片描述
代码:

from pyecharts.render import make_snapshot
from snapshot_phantomjs import snapshot

# grid存放了一些图像
make_snapshot(snapshot, grid.render(), "pdf/" + file_name + ".pdf")
make_snapshot(snapshot, grid.render(), "pdf/" + file_name + ".png")

除了需要pip安装一下snapshot_phantomjs外,还需要下载一下phantomjs-2.1.1-windows,将下图这个的路径放入系统环境变量Path,就是让程序调用时可以找到它。
在这里插入图片描述

html输出为pdf

另外,我还尝试了一些包,但是在将html打印为pdf时会出现以下几种情况:

  1. 打印出的pdf是空白的
  2. 能打印出坐标轴,但没有折线图像

这些包在打印标准格式的html时是ok的,所以下面将列出代码存档备用。

下面的包都是在anaconda中使用pip安装的,如果有问题自行搜素。

weasyprint

from weasyprint import HTML
HTML("7024.html").write_pdf("7024.pdf")

如果遇到找不到cairo/cairo2之类的库,很可能是因为没装gtk,装一个gtk2或者gtk3即可解决。

pdf_reports

https://github.com/Edinburgh-Genome-Foundry/pdf_reports/blob/master
这个包其实是基于weasyprint的。

from pdf_reports import write_report
write_report("html/7024.html", "example.pdf")

PyQt5

印象中这个是打印不出折线图像。坐标轴和文字附注是能打印出来的。

from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
from PyQt5.QtCore import QMarginsF
from PyQt5.QtPrintSupport import QPrinter
from PyQt5.QtGui import QPageLayout, QPageSize
import sys

app = QtWidgets.QApplication(sys.argv)
loader = QtWebEngineWidgets.QWebEngineView()
loader.load(QtCore.QUrl('file:///本地地址/7024.html'))

layout = QPageLayout(
    QPageSize(QPageSize.A4),
    QPageLayout.Portrait, QMarginsF(0, 0, 0, 0)
)

def printFinished():
    page = loader.page()
    print("%s Printing Finished!" % page.title())
    app.exit()

def printToPDF(finished):
    loader.show()
    time.sleep(60)
    page = loader.page()
    page.printToPdf("E:\pdf%s.pdf" % page.title(), layout)


loader.page().pdfPrintingFinished.connect(printFinished)
loader.loadFinished.connect(printToPDF)

app.exec_()

pdfkit

下载wkhtmltopdf,然后放到系统环境变量Path。
https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_msvc2015-win64.exe

import pdfkit
pdfkit.from_file('test.html', 'out.pdf')
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:24:53  更:2022-11-05 00:28:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 13:01:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码