利用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 相关文章推荐
python的绘图工具matplotlib使用实例
Jul 03 Python
对Python新手编程过程中如何规避一些常见问题的建议
Apr 01 Python
Python脚本处理空格的方法
Aug 08 Python
详解Python中表达式i += x与i = i + x是否等价
Feb 08 Python
Python爬虫中urllib库的进阶学习
Jan 05 Python
python调用百度语音识别实现大音频文件语音识别功能
Aug 30 Python
python实现小球弹跳效果
May 10 Python
python不同系统中打开方法
Jun 23 Python
基于pytorch中的Sequential用法说明
Jun 24 Python
Python变量及数据类型用法原理汇总
Aug 06 Python
基于Python 函数和方法的区别说明
Mar 24 Python
python实现批量提取指定文件夹下同类型文件
Apr 05 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实现文件安全下载
2006/10/09 PHP
10个可以简化php开发过程的MySQL工具
2010/04/11 PHP
javascript 动态添加事件代码
2008/11/30 Javascript
jQuery is()函数用法3例
2014/05/06 Javascript
jquery动态添加删除一行数据示例
2014/06/12 Javascript
jQuery中contents()方法用法实例
2015/01/08 Javascript
javascript设置和获取cookie的方法实例详解
2016/01/05 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
2016/02/26 Javascript
vue.js中$watch的用法示例
2016/10/04 Javascript
jQuery插件HighCharts绘制的基本折线图效果示例【附demo源码下载】
2017/03/07 Javascript
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
微信小程序 实现点击添加移除class
2017/06/12 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
详解ES6通过WeakMap解决内存泄漏问题
2018/03/09 Javascript
vue如何将v-for中的表格导出来
2018/05/07 Javascript
微信小程序实现聊天对话(文本、图片)功能
2018/07/06 Javascript
JavaScript ES6箭头函数使用指南
2018/12/30 Javascript
js计时事件实现圆形时钟
2020/03/25 Javascript
javascript实现左右缓动动画函数
2020/11/25 Javascript
windows7 32、64位下python爬虫框架scrapy环境的搭建方法
2018/11/29 Python
Python不同目录间进行模块调用的实现方法
2019/01/29 Python
python中类的输出或类的实例输出为这种形式的原因
2019/08/12 Python
python 使用tkinter+you-get实现视频下载器
2020/11/17 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
canvas生成带二维码海报的踩坑记录
2019/09/11 HTML / CSS
美国女鞋品牌:naturalizer(娜然)
2016/08/01 全球购物
俄罗斯童装网上商店:BebaKids
2020/06/06 全球购物
理工大学毕业生自荐信
2013/11/01 职场文书
中学生寄语大全
2014/04/03 职场文书
学生党员批评与自我批评
2014/10/15 职场文书
党的群众路线教育实践活动专题组织生活会发言材料
2014/10/17 职场文书
简易离婚协议书范本
2014/10/24 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python
详解TypeScript的基础类型
2022/02/18 Javascript