本文档记录了如何使用python中pyecharts绘制双纵坐标图,并将输出的html文件转为png等图片格式。
0 背景
项目中需要绘制双纵坐标图,在网上调研之后,发现使用pyecharts绘制起来更方便,且看上去还挺美观,果断抄作业~
【当然,强大的excel也能绘制,但是整个项目的数据处理过程都在python中,所以你懂得~】
后续制作分析报告时,需要使用图片格式数据,但是pyecharts输出的是html文件,前期懒省事,制作分析报告时都是采用将html文件截图生成图片的方式,如果是一两个图片就还行。。。。凡事都有但是,当这个工作变成持续大量的时候,就会觉得有点恶心。。。于是乎,痛下决心,解决一下这个需求。
1 双坐标
简单介绍一下项目中所涉及的双纵坐标图长什么样,假设数据如下:
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"] label1 = [100, 100, 36, 20, 10, 10] label2 = [round(i / sum(label1) * 100, 2) for i in label1] # label2: [36.23, 36.23, 13.04, 7.25, 3.62, 3.62]
横坐标表示不同类型的衣服,左纵坐标表示衣服数量,右纵坐标表示衣服数量占比。
话不多说,代码展示:
from pyecharts.charts import Line, Bar from pyecharts.globals import ThemeType from pyecharts import options as opts def overlap_bar_line(x, y1, y2, title) -> Bar: bar = ( Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK)) # 初始化柱状图,并设置主题 .add_xaxis(x) # 设置横坐标 .add_yaxis("数量", y1, bar_width=20) # 设置左纵坐标 .extend_axis( yaxis=opts.AxisOpts( axislabel_opts=opts.LabelOpts(formatter="{value}%"), interval=5 ) ) # 增加右纵坐标设置 .set_series_opts(label_opts=opts.LabelOpts(is_show=False)) # 柱状图上的数字是否显示 .set_global_opts( title_opts=opts.TitleOpts(title=title), yaxis_opts=opts.AxisOpts( axislabel_opts=opts.LabelOpts(formatter="{value}") ), xaxis_opts=opts.AxisOpts( axislabel_opts=opts.LabelOpts( is_show=True, position="top", color="pink", rotate=15, interval=0 ) ), ) # 整体格式设置 ) line = ( Line().add_xaxis(x).add_yaxis("总数量占比", y2, yaxis_index=1, z_level=1) ) # 增加右纵坐标数值 bar.overlap(line) return bar overlap_bar_line(attr, label1, label2, "双坐标图示例").render("test.html")
代码运行成功后,会在项目所在文件夹下生成test.html文件,绘制的结果如下所示:
2 图片格式转换
如何将html文件转换为png等图片格式呢,在网上调研之后,主要参考:
PyEcharts输出保存图片的多种方法_Python美丽星球--微信(Felixzfb)-优快云博客
这篇博客中提到的方法1,但是中间出了点小插曲,下面记录一下bug和解决方法。
先说下我的环境吧,
mac 10.15.4 python 3.7.6 pyecharts==1.8.1 谷歌浏览器版本:91.0.4472.77 且谷歌浏览器受内网严格控制。
话不多说,也是先上实现的代码,
from pyecharts.render import make_snapshot from snapshot_selenium import snapshot # 修改了源码,更改chromedriver的地址 make_snapshot( snapshot, overlap_bar_line(attr, label1, label2, "双坐标图示例").render(), "test.png" )
如果代码运行成功,会在项目所在路径生成名为test.png的图片,就是我想要的!
函数make_snapshot的第二个参数我用的是自定义的绘制双纵坐标的函数产生的文件,可以改成自己的。
第三个参数是你想要生成的图片格式和名字,后缀可以使用下列形式【make_snapshot源码中设置的】:
PNG_FORMAT = "png" JPG_FORMAT = "jpeg" GIF_FORMAT = "gif" PDF_FORMAT = "pdf" SVG_FORMAT = "svg" EPS_FORMAT = "eps" B64_FORMAT = "base64"
3 实现细节
下面开始说一下,在代码成功运行之前需要做的步骤:
-
按照博客中提到的方法步骤,首先进行:
pip install snapshot-selenium
我下载的版本是snapshot-selenium==0.0.2
-
随后,要下载谷歌驱动器chromedriver,网址:ChromeDriver - WebDriver for Chrome - Downloads 下载与你浏览器差不多对应的版本,我下载的是:ChromeDriver 91.0.4472.101
但是在代码调用chromedriver时出现了小插曲,一直出现下面的错误:
json Message: ‘chromedriver’ executable needs to be in PATH.
我先后采用了博客中提到的方法:
(1)将chromedriver添加到系统路径中
我参考是的这两篇博客:
Mac下chromedriver安装配置_YooHoeh的博客-优快云博客
Mac 安装Chromedriver及配置_Python之家-优快云博客
【不起作用,公司电脑我没有权限操作系统变量,我只能操作个人Applications下的内容,但是我把chromedriver放到个人Applications下,再将其添加到系统路径中时,在调用的时候还是找不到。。。哪位大神若是知道解决办法也可告知我啊。。。】
卒
(2)将chromedriver放在项目文件所在的文件夹下
博客中提到他采用这种方法解决了,无奈我还是不行啊,我连试了两个项目,都不奏效,还是上面那个错误。。。【我在个人电脑windows系统下,不受外网限制,试了这种方法,已经凑效,下面的内容可以忽略了。。。】
卒
(3)第三种方法!手动指定chromedriver的位置
强烈推荐这个参考网址:
https://www.roelpeters.be/solve-message-chromedriver-executable-neneeds-to-be-in-path/
自己要是早点发现这个就好了!或许我可以多一点摸鱼的时间~
怎么指定?
首先定位到 snapshot_selenium.snapshot.py 文件中的 get_chrome_driver() 函数:
def get_chrome_driver(): options = webdriver.ChromeOptions() options.add_argument("headless") return webdriver.Chrome( executable_path="/Users/chromedriver", options=options, ) # add path
在webdriver.Chrome()中,将executable_path设置成你自己下载的解压后的chromedriver的位置,完成!
小贴士:在运行代码时,我需要将网络切换到外网,内网限制下程序会一直停在那里,猜测是加载不出来谷歌,我可真是太难了!
4 其他
一开始尝试的是博客中提到的方法2,参考的是:
将pyecharts生成的网页保存为图像格式的方法(2020.3)_snail82的博客-优快云博客
确实要复杂点,但是没解决我的问题,就。。。这样吧!
5 总结
本文档整体上记录了使用pyecharts绘制双纵坐标图以及转换为png等图片格式的方法。
如有问题,不吝赐教。