问题描述

昨天一直在搞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 JsCodedef 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,),

颜色不止可以使用navy,red之类的,也可以传递rgb值。

linestyle_opts=opts.LineStyleOpts(color='#0000CC')

更改线条属性(颜色、宽度等)

.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),)

如果想搞成阶梯式的线条,可以加:

is_step=True,

设置好之后如下图所示:

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掉,是可以实现我要的效果的。

2022/11/6更新:JsCode控制坐标轴标签实例-以科学计数法显示刻度值

使用正则表达式控制格式。其实就是javascript,稍微改一下就行(但是一些js的函数不能用,我不懂为什么)

formatter=JsCode('''function(value){var p1=/[1-9][.][1-9][E]/g;var p2=/0[.][1-9][E]/g;if (value == '0') {return '0.0E+000';} else {var s = value + 'E';if(s.match(p1)){return value + 'E+00' + 'TAIL';                                        }else if(s.match(p2)){return s.substr(2,1) + '.0E+00' + 'MIN';}else {console.log(s);return value + '.0E+00' + 'TAIL';}}}'''.replace('TAIL', str(index_y)).replace('MIN', str(index_y-1))
),

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='12px "Courier New"', # 字号和字体# 文字颜色graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(fill='navy')),),
],

在搜索时,我一开始没去看官方文档,结果font那里少了font-family外的引号,导致设置失败。
一定要去看官方文档!!!官方说的很清楚,font-family要用引号括起来。

输出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,就是让程序调用时可以找到它。

加快make_snapshot的速度

这里尝试了改国内源,但是,在输出的png图像中,有相当一部分丢失了图像的细节(比如刻度少了或者没有线条),个人不是很懂是什么原理,而且使用国内源速度并无明显提升(可能打开html时会更快,但对打png的速度没啥影响)。以后有时间再研究这个问题吧。

from pyecharts.globals import CurrentConfig
# 然后在绘图前加入:
CurrentConfig.ONLINE_HOST = "https://cdn.jsdelivr.net/npm/echarts@latest/dist/"

之后可以去看打出的html源代码(顶部引用资源处),已经改为国内源的了。

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 sysapp = 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-pyecharts绘图-坐标轴标签格式化formatter+刻度调整+批量输出为pdf相关推荐

  1. python plt 绘图,双轴设置刻度,步长,使用栅格,以base64格式输出

    def make_plt(context, host, status):# 定义y轴展示信息字典label1_dict = {'0': 'in_bytes', '1': 'out_bytes', '2 ...

  2. Python matplotlib可视化:自定义轴标签格式化函数(在轴刻度上添加自定义的数值以及符号形式)、使用自定义函数在Matplotlib中为坐标轴刻度添加自定义符号(例如,货币符号¥$等)

    Python matplotlib可视化:自定义轴标签格式化函数(在轴刻度上添加自定义的数值以及符号形式).使用自定义函数在Matplotlib中为坐标轴刻度添加自定义符号(例如,货币符号¥$等) 目 ...

  3. Python+matplotlib绘图使用Latex引擎渲染坐标轴刻度文本上标

    问题描述: 在使用matplotlib进行数据可视化或科学计算可视化时,有时候数值过大或过小,使得坐标轴刻度显示不方便,这时可以考虑使用科学计数法,例如把10000显示为,把0.00001显示为. 在 ...

  4. Python使用matplotlib可视化柱状图、坐标轴标签的符号(-)显示为了方框□□、设置rcParams参数配置解决

    Python使用matplotlib可视化柱状图.坐标轴标签的符号(-)显示为了方框□□.设置rcParams参数配置解决 目录

  5. matlab 坐标轴刻度朝外_Matlab 绘图 坐标轴 刻度

    [转载]Matlab 绘图 坐标轴 刻度 原文出处:http://blog.sina.com.cn/s/blog_4b1fb7610100q9ov.html matlab中坐标轴的刻度如何设置? 用m ...

  6. python条形图一直长_条形图的坐标轴标签过长,怎么优化更美观呢?

    今日分享主题:当条形图标签过长,该怎么优化呢? 先说明下:本文操作使用的是2019版本,2013版本以上操作界面也差不多.如果是2013以下版本,操作界面可能会有差异,但功能都有,要自己找找. 昨天的 ...

  7. python极坐标图定义角度范围_python-matplotlib极坐标刻度/轴标签位置

    我一直在寻找一种方法来可靠地将刻度和轴标签定位在极坐标图中.请看下面的例子: import numpy as np import matplotlib.pyplot as plt fig = plt. ...

  8. python画图 调整坐标轴标签位置 ylabel/xlabel位置 python pyplot 坐标轴交叉点 文本竖着排列 plt.xlabel 竖着 pyplot折线图横坐标竖着显示

    文章目录 调整坐标轴标签位置 ylabel/xlabel位置 坐标轴交叉点 plt.xlabel 竖着 调整坐标轴标签位置 ylabel/xlabel位置 更新:评论区的伙伴给了更好的解决方案 参考链 ...

  9. Python Matplotlib绘图的正确打开方式

    Python Matplotlib绘图的正确打开方式 文章目录 Python Matplotlib绘图的正确打开方式 1.先搞懂fig.axes.axis `Figure` `Axes` `Axis` ...

最新文章

  1. linux下redmine3.3迁移、升级、插件备忘录
  2. webpack 入口文件 php,webpack,jsx_webpack jsx 找不到入口文件,webpack,jsx - phpStudy
  3. 中报亮眼,阅文的增长“飞轮”是如何练成的?
  4. “病毒防治”页面中“社区热帖”版块不显示
  5. 筛选法求1到100以内的素数
  6. 蓝桥杯 历届试题 带分数
  7. Mac精品软件分享第二期
  8. AcWing 1236. 递增三元组 (flag + 前缀和 | 二分 | 滑动窗口)
  9. 看到的精彩的地方 分享下
  10. 现学活用的XPath爬取豆瓣音乐
  11. 获得客户端真实IP的方法
  12. 如何进行航拍全景摄影(上)
  13. 练习-Java类和对象之包的定义(17)
  14. android iphone 记事本,苹果手机上有简单实用的便签记事本app吗?
  15. 转:授之于鱼还是授之以渔,金蝶给了企业SaaS一个完整答案
  16. 「 Gazebo仿真 」地图创建、多模型显示、基本指令
  17. 通过bower 下载管理angularjs
  18. 信号量哲学家问题java_利用AND信号量机制解决哲学家进餐问题
  19. 力天创见客流、热区系统WEB管理
  20. 51单片机入门学习 第八天

热门文章

  1. Linux系统下载echarts,echarts图形展示
  2. 【转载】Android音频(7)——项目实战——耳麦插拔
  3. 商场三十六计——第33计 “苦肉计”
  4. 【OSM历史数据获取及处理】
  5. Python3数据结构
  6. AI智能视频审核|图普科技高效把控短视频平台用户的内容生产
  7. 显示图片实现上一张下一张功能
  8. 异常处理——bindtap/catchtap绑定事件冒泡情况
  9. DAMP平台logo初版
  10. css 文字动态特效