利用python在excel中画图的实现方法


Posted in Python onMarch 17, 2020

一、前言

以前大学时候,学EXCEL看到N多大神利用excel画图,觉得很不可思议。今个学了一个来月python,膨胀了就想用excel画图。当然,其实用画图这个词不甚严谨,实际上是利用opencv遍历每一个像素的rgb值,再将其转化为16进制,最后调用openpyxl进行填充即可。

1.1、实现效果

效果如下图

利用python在excel中画图的实现方法

1.2、需要用到的库的安装

需要用到库如下:

import cv2   #导入OpenCV库
import xlsxwriter #利用这个调整行高列宽
import openpyxl  #利用这个填充颜色
import numpy as np #下面这两个是数据存储的两种方式,用此种方式处理数据,比列表高效,具体可自行查看文档
import pandas as pd

除了第一个库其他的可以直接用pip在命令提示行进行安装,或者利用编辑器的一些自动安装功能也非常的方便,具体的请参看这篇文章 的第三节: 三、开始安装

第一个库如果你直接用pip3 install opencv-python 进行安装的话,无论你网速多么快,都会非常慢几k/s,如下:

利用python在excel中画图的实现方法

如果能安装好还行,关键有的可能等上几分钟也不行,直接出现几十行的红色字看的头疼。几经百度后才知道是安装源的问题,切换为国内的安装源即可,利用如下命令,

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

如下图,我准备截取安装速度和上面的作对比的,结果直接安装好了

利用python在excel中画图的实现方法

二、代码分开讲解

本文我们利用面相对象的编程思维进行。

2.1、对象的定义以及初始化

class ImageToExcel():
 def __init__(self,image_path,excel_path):
  self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)
  self.excel_path=excel_path

前面两行很好理解就是定义对象的格式以及初始化对象

其中image_path和excel_path这两个变量是你的图像储存路径和后续的excel文件保存位置。

第三行self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)意思是调用opencv的imread读取图片。其中第一个参数就是对象实例化时候传递进来的图像储存路径。该函数返回的是一个三维数组,分别表示x,y,rgb 就是x,y坐标对应的rgb值,其中x,y单位为1像素。最后将这个三维数组传递给对象的一个属性imgviewx,等待后续对象方法调用。我们将之打印出来如下。

利用python在excel中画图的实现方法

第四行<<self.excel_path=excel_path>>是将对象实例化时候传递进来的excel_path传递给对象的属性excel_path,同样等待后续对象的方法调用。

2.2、对象的方法

1:行高列宽调整,以防止图像变形

#excel行高列宽调整
 def excel_size(self):
  workbook = xlsxwriter.Workbook(self.excel_path)
  worksheet = workbook.add_worksheet('test')
  worksheet.set_column('A:CAA', 1)
  for x in range(2000):worksheet.set_row(x, 8.4)
  workbook.close()

这个其实你可以后续在excel中调整也可以。
第二行第三行基本一看就懂,就是在你刚开始对象实例化时候传入的一个路径中创建一个工作簿并添加一个名为test的工作表。
第三行意思是将A列到CAA列的列宽设置为1(注意:这里面设置为1不知道为什么在工作表中就是0.94,列宽同样小点
第四行意思同样,不过行高不能批量只能通过循环。
最后一样看着像关闭,其实最主要功能是保存,没有这一行,前面的所有设置都不会被保存。

2.3、对象的方法2:10进制转化为16进制

#10进制转化为16进制
 def ten2_16(self,num):
  num1 = hex(num).replace('0x', '')
  return num1 if len(num1) > 1 else '0' + num1

这个方法不用细说,就是利用系统自带的函数hex将10进制转化为16进制。我们都知道hex返回的16进制是以0x开头的,而16进制颜色码中明显没有,所以要用replace去掉。
如果rgb值是16以内的,以16进制显示的话会是1位数,而同样这个在16进制颜色码中也没有,所以最后一行的意思就是一位数的话在开头补0。

2.4、对象的方法3:获取r、g、b值并运用方法1转化为16进制颜色码

#获取像素数据并转化为16进制
 def get_rgb_data(self):
  self.excel_size()
  data_r=pd.DataFrame( np.array(self.imgviewx)[:,:,2] ).applymap(self.ten2_16)
  data_g=pd.DataFrame( np.array(self.imgviewx)[:,:,1] ).applymap(self.ten2_16)
  data_b=pd.DataFrame( np.array(self.imgviewx)[:,:,0] ).applymap(self.ten2_16)
  return (data_r+data_g+data_b).values

其中第二行<<self.excel_size() >>是在本方法本调用时候先调用方法1调整行高列宽。我们后面说,这关系到对象方法之间的参数传递,我们后续说。
三四五行的代码结构一样,我们挑一个说。比如第三行data_r=pd.DataFrame( np.array(self.imgviewx)[:,:,2] ).applymap(self.ten2_16)这个代码我们可以拆开成下面的代码

r=np.array(self.imgviewx)[:,:,2]
tmp=pd.DataFrame( r )
data_r=tmp.applymap(self.ten2_16)

这下就容易懂了
第一行意思是将刚开始对象初始化时候得到的包含目标图片的所有像素点的rgb值的三维列表转化为数组并提取其中的r。
第二行是将第一行得到的数组转化为DataFrame对象并存储在tmp变量中,以便第三行的处理。
第三行是利用DataFrame中的applymap将r值转化为16进制。

最后一行<<return (data_r+data_g+data_b).values>>意思是将转化为16进制的rgb值合并后就得到了16进制的颜色码并转化为数组。

2.5、对象的方法4;颜色填充

def color_fill(self):
  rgb_list=self.get_rgb_data()
  wb = openpyxl.load_workbook(self.excel_path)
  ws = wb['test']
  for x,tmp1 in list(enumerate(rgb_list)):
   print('总共有%s行,已填充%s行,还剩下%s行'%(len(rgb_list),x+1,len(rgb_list)-x-1))
   for y ,tmp2 in list(enumerate(tmp1)):
    ws.cell(x+1,y+1).fill = openpyxl.styles.fills.GradientFill(stop=[str(tmp2),str(tmp2)])
  wb.save(self.excel_path)

第二行<<rgb_list=self.get_rgb_data()>>是不是似曾相识,对,就是在方法2中调用方法1时候用的。
这里就是在本方法也就是方法3中调用方法2。唯一的区别就是有没有返回值。
我们这样在方法3中调用方法2然后方法2中调用方法1。这样在对象外的时候我们就只用对象实例化并调用方法3即可实现功能。
第三行、第四行就是调用openpyxl.load_workbook打开我们在方法1中新建的工作簿中的test工作表
五到七行两个循环嵌套很容易懂就是利用循环遍历每个工作表
第八行的代码可能可以简化 ,这个是我修改网上的一个填充渐变色的代码。
最后一行就是工作表的保存,没什么可说的。

三、完整代码

import cv2   #导入OpenCV库
import xlsxwriter #利用这个调整行高列宽
import openpyxl  #利用这个填充颜色
import numpy as np #下面这两个是数据存储的两种方式,用此种方式处理数据,比列表高效
import pandas as pd

class ImageToExcel():
 #初始化
 def __init__(self,image_path,excel_path):
  self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)
  self.excel_path=excel_path
 # excel行高列宽调整
 def excel_size(self):
  workbook = xlsxwriter.Workbook(self.excel_path)
  worksheet = workbook.add_worksheet('test')
  worksheet.set_column('A:CAA', 1)
  for x in range(2000): worksheet.set_row(x, 8.4)
  workbook.close()
 #rgb转16进制颜色码
 def ten2_16(self,num):
  tmp = hex(num).replace('0x', '')
  return tmp if len(tmp) > 1 else '0' + tmp
 #获取像素数据并转化为16进制
 def get_rgb_data(self):
  self.excel_size()
  data_r=pd.DataFrame( np.array(self.imgviewx)[:,:,2] ).applymap(self.ten2_16)
  data_g=pd.DataFrame( np.array(self.imgviewx)[:,:,1] ).applymap(self.ten2_16)
  data_b=pd.DataFrame( np.array(self.imgviewx)[:,:,0] ).applymap(self.ten2_16)
  return (data_r+data_g+data_b).values
 #颜色填充
 def color_fill(self):
  rgb_list=self.get_rgb_data()
  wb = openpyxl.load_workbook(self.excel_path)
  ws = wb['test']
  for x,tmp1 in list(enumerate(rgb_list)):
   print('总共有%s行,已填充%s行,还剩下%s行'%(len(rgb_list),x+1,len(rgb_list)-x-1))
   for y ,tmp2 in list(enumerate(tmp1)):
    ws.cell(x+1,y+1).fill = openpyxl.styles.fills.GradientFill(stop=[str(tmp2),str(tmp2)])
  wb.save(self.excel_path)
excel_path='test23.xlsx'
image_path='tttt.png'
image=ImageToExcel(image_path,excel_path)
image.color_fill()

最后四行前两行可以直接写在第三行中,就是对象的实例化中
另外还有一点,image_path中的 tttt.jpg是直接和我的py文件放在一起的,不然运行会报错。

四、结语

好啦,到此所有东西已全部搞定,当然还有很多要注意的,
第一、方法3中红绿蓝的提取中这部分的编号是刚好相反的,提取时候需要注意
如下

利用python在excel中画图的实现方法

当然你也可以尝试改变这个值看最后会得到什么结果。蓝色的太阳 红色的天空 或者是绿色的帽子,哈哈 好吧这个就你们自己发挥了。
第二、除了以上一点需要注意的,还有一个需要注意,就是像素不能太高。我测试了下342*218的话我的i7-6700u打开excel就不是很流畅了。
你可以遍历的时候以2个像素点或者四个像素点为步长,不过这样我没试过,可能颗粒感比较明显吧(自己猜测没试过),或者把原始图片修改下。

到此这篇关于利用python在excel中画图的实现方法的文章就介绍到这了,更多相关python excel画图内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
wxpython中自定义事件的实现与使用方法分析
Jul 21 Python
python实现多线程行情抓取工具的方法
Feb 28 Python
Python Unittest自动化单元测试框架详解
Apr 04 Python
Php多进程实现代码
May 07 Python
windows下python安装pip图文教程
May 25 Python
python正则表达式去除两个特殊字符间的内容方法
Dec 24 Python
浅析Windows 嵌入python解释器的过程
Jul 26 Python
Python列表list操作相关知识小结
Jan 29 Python
Python+Appium实现自动化测试的使用步骤
Mar 24 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
Mar 30 Python
Python实现电视里的5毛特效实例代码详解
May 15 Python
实现ECharts双Y轴左右刻度线一致的例子
May 16 Python
Python reversed函数及使用方法解析
Mar 17 #Python
使用python自动追踪你的快递(物流推送邮箱)
Mar 17 #Python
windows、linux下打包Python3程序详细方法
Mar 17 #Python
Python任务自动化工具tox使用教程
Mar 17 #Python
vue常用指令代码实例总结
Mar 16 #Python
django-利用session机制实现唯一登录的例子
Mar 16 #Python
python安装dlib库报错问题及解决方法
Mar 16 #Python
You might like
php根据分类合并数组的方法实例详解
2013/11/06 PHP
33道php常见面试题及答案
2015/07/06 PHP
PHP命名空间和自动加载类
2016/04/03 PHP
php 读写json文件及修改json的方法
2018/03/07 PHP
javascript下function声明一些小结
2007/12/28 Javascript
js+CSS 图片等比缩小并垂直居中实现代码
2008/12/01 Javascript
JS跨域总结
2012/08/30 Javascript
javascript中方便增删改cookie的一个类
2012/10/11 Javascript
javascript+html5实现仿flash滚动播放图片的方法
2015/04/27 Javascript
nodejs实现遍历文件夹并统计文件大小
2015/05/28 NodeJs
AngularJS实现全选反选功能
2015/12/08 Javascript
jQuery 实现评论等级好评差评特效
2016/05/06 Javascript
浅析Bootstrap表格的使用
2016/06/23 Javascript
Javascript的动态增加类的实现方法
2016/10/20 Javascript
JS跨域请求外部服务器的资源
2017/02/06 Javascript
详解关于react-redux中的connect用法介绍及原理解析
2017/09/11 Javascript
vue2实现搜索结果中的搜索关键字高亮的代码
2018/08/29 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
解决Vue项目中tff报错的问题
2020/10/21 Javascript
Python代理抓取并验证使用多线程实现
2013/05/03 Python
朴素贝叶斯算法的python实现方法
2014/11/18 Python
Python的dict字典结构操作方法学习笔记
2016/05/07 Python
利用Python实现图书超期提醒
2016/08/02 Python
Python之pandas读写文件乱码的解决方法
2018/04/20 Python
浅谈python多线程和多线程变量共享问题介绍
2020/04/17 Python
pandas分批读取大数据集教程
2020/06/06 Python
html5的画布canvas——画出弧线、旋转的图形实例代码+效果图
2013/06/09 HTML / CSS
转党组织关系介绍信
2014/01/08 职场文书
小学中秋节活动方案
2014/02/06 职场文书
普通大学毕业生自荐信范文
2014/02/23 职场文书
党员个人公开承诺书
2014/08/29 职场文书
国富论读书笔记
2015/06/26 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
为什么代码规范要求SQL语句不要过多的join
2021/06/23 MySQL
JavaScript执行机制详细介绍
2021/12/06 Javascript
Python中npy和mat文件的保存与读取
2022/04/24 Python