[Python]使用matplotlib库实现在Cell中不完全填充颜色

本文介绍了如何使用matplotlib库在生成表格图片时,根据百分比不完全填充单元格颜色。通过覆盖Cell对象的draw方法,动态计算并绘制额外的矩形色块,实现了进阶的图表展示效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图镇楼

在这里插入图片描述
想看细节的可以一点点看,想Copy代码的,直接看下面代码部分

背景

最近在研究使用matplotlib直接从数据生成表格图片的实现方式。
进阶需求是把其中一列按百分比使背景色从左到右填充单元格,这里给出了一个可以用来解决问题的方法。

实现相关的技术点

  1. matplotlib绘制图表时的x,y是坐标轴里的x,y,并不是像素位置
  2. Table类有一个字典是用来保存行列元组和对应位置Cell的成员变量
  3. Cell类继承于Rectangle类,绘制的方式是绘制一个矩形然后填充下文字
  4. Rectangle类主要由左下角顶点在坐标系里的坐标,矩形的宽,矩形的高几个成员变量组成
  5. 每个Cell对象的左下角顶点坐标只有在最后保存图片进行绘制时才会去计算其位置(在执行object_of_cell.draw(renderer)之前)
  6. 可以通过object_of_cell.draw = MethodType(new_draw_method,object_of_cell)的方式指定object_of_cell这个对象的draw方法是new_draw_method
  7. Python中的对象可以动态增加成员变量

实现思路

利用技术点6和5,可以在绘制Cell的时候多绘制一个矩形出来作为百分比条,宽度可以通过技术点7来设置

实现步骤(不包含各种读取数据&生成Table对象的逻辑)

  1. 新写一个方法new_draw(self,renderer)作为绘制格子时的函数的逻辑,绘制原本的方框,利用原本的左下角顶点坐标绘制新的百分比填充的色块,最后填充文本
  2. 使用数据生成一个Table对象后,遍历其中Cell,对于符合条件的格子增加一个成员变量inner_width,保存百分比小格子的宽度,也就是当前格子宽度*这个格子保存的浮点数,区间[0,1],然后指定这个Cell对象的draw方法是上面新写的new_draw方法
  3. 最后保存的时候特殊格子调用的draw方法是我们新写的方法,就可以实现想要的功能了

实现代码

  1. new_draw方法的代码
def draw_processing_bar_cell(self, renderer):
    if not self.get_visible():
        return
    # draw the rectangle
    table_lib.Rectangle.draw(self, renderer)

    # 绘制一个不完全填充整个格子的矩形,这里可以根据个人需求进行编码
    old_width = self.get_width() # 这里需要记录下原来的宽度,等下文本的居中对齐会用这个宽度进行对齐,画完条要进行还原
    self.set_width(self.inner_width)
    if self.processing_bar_color is None:
        self.processing_bar_color = '#FFDAB9'
    self.set_facecolor(self.processing_bar_color)
    self.set_alpha(0.5)
    self.set_edgecolor(None)
    patches.Rectangle.draw
<think>我们已知用户想要使用Python设置Excel单元格颜色,并且希望通过RGB值而是十六进制代码来设置。 在openpyxl中,设置单元格颜色通常使用十六进制代码。但是,用户希望使用RGB值。因此,我们需要将RGB值转换为十六进制字符串。 步骤: 1. 将RGB的三个整数(每个值在0-255之间)转换为一个十六进制字符串,格式为"RRGGBB"。 2. 使用openpyxl的PatternFill来填充单元格,设置fill_type为"solid",然后设置fgColor为这个十六进制字符串。 注意:openpyxl的Colors类需要传入一个十六进制字符串(带#)或者一个aRGB字符串(带透明度)。我们这里只需要普通的RGB。 另外,参考引用[2]中提到了颜色设置,但它是关于matplotlib样式表的,与Excel操作无关。过,我们可以忽略这个引用,因为用户的问题是关于Excel的。 根据用户上一次的问题,他可能已经知道如何通过切片获取单元格范围(引用[1]),所以我们可以结合这个知识。 因此,解决方案如下: 1. 编写一个将RGB转换为十六进制字符串的函数。 2. 使用openpyxl的PatternFill设置单元格的填充颜色。 示例代码: 假设我们有一个RGB元组(255, 0, 0)表示红色,转换为十六进制字符串为"FF0000"。 我们还需要注意:openpyxl中,设置单元格颜色使用PatternFill,并且要设置fill_type='solid',然后fgColor为转换后的十六进制字符串。 另外,引用[3]提到关于内存节省的问题,但这里相关。 因此,我们将提供以下步骤: 1. 导入openpyxl 2. 加载工作簿 3. 选择工作表 4. 定义RGB转十六进制函数 5. 使用该函数转换RGB值 6. 创建PatternFill对象 7. 应用到指定单元格或单元格范围 代码示例: """ import openpyxl from openpyxl.styles import PatternFill def rgb_to_hex(rgb): # 将RGB元组转换为十六进制字符串,带# return '{:02X}{:02X}{:02X}'.format(rgb[0], rgb[1], rgb[2]) # 加载工作簿 wb = openpyxl.load_workbook('example.xlsx') ws = wb.active # 设置颜色,例如红色:RGB(255,0,0) rgb_red = (255, 0, 0) hex_color = rgb_to_hex(rgb_red) # 创建填充 fill = PatternFill(fill_type='solid', fgColor=hex_color) # 应用到单个单元格,例如A1 ws['A1'].fill = fill # 或者应用到范围,例如A1:C2 for row in ws['A1':'C2']: for cell in row: cell.fill = fill # 保存工作簿 wb.save('example_modified.xlsx') """ 注意:如果用户想要设置的是背景色,那么使用PatternFill即可,因为Excel单元格的背景色是通过填充实现的。 另外,如果用户需要设置字体颜色,则使用Font对象,并设置color属性,同样需要十六进制字符串。但用户问题中只提到了单元格颜色,我们默认为背景色。 因此,我们按照以上步骤回答用户。</think>### Python 使用 RGB 值设置 Excel 单元格颜色Python 中操作 Excel 时,虽然 `openpyxl` 默认使用十六进制代码设置颜色,但可通过 RGB 值转换实现需求。以下是完整解决方案: #### 核心步骤 1. **RGB 转十六进制函数** 创建转换函数处理 RGB 值(0-255范围): ```python def rgb_to_hex(r, g, b): return f"{r:02X}{g:02X}{b:02X}" # 格式化为 6 位十六进制字符串 ``` 2. **设置单元格颜色** 使用 `PatternFill` 应用转换后的颜色: ```python from openpyxl import load_workbook from openpyxl.styles import PatternFill # 转换 RGB (如红色: 255,0,0 -> "FF0000") hex_color = rgb_to_hex(255, 0, 0) # 创建填充样式 red_fill = PatternFill( fill_type="solid", fgColor=hex_color # 应用十六进制值 ) # 应用到单元格 wb = load_workbook("文件.xlsx") ws = wb.active ws["A1"].fill = red_fill # 设置 A1 单元格 wb.save("结果.xlsx") ``` #### 关键说明 1. **颜色范围验证** RGB 值需在 `0-255` 之间,超出范围将抛出异常,建议添加校验: ```python if not (0 <= r <= 255) or not (0 <= g <= 255) or not (0 <= b <= 255): raise ValueError("RGB 值必须在 0-255 范围内") ``` 2. **范围设置技巧** 参考切片操作批量设置颜色[^1]: ```python for row in ws["B2":"D4"]: # 设置 B2 到 D4 区域 for cell in row: cell.fill = red_fill ``` 3. **透明度扩展** 如需 RGBA(带透明度),扩展为 8 位十六进制: ```python def rgba_to_hex(r, g, b, a): return f"{a:02X}{r:02X}{g:02X}{b:02X}" # 格式: AARRGGBB ``` #### 完整示例 ```python from openpyxl import Workbook from openpyxl.styles import PatternFill def rgb_to_hex(r, g, b): return f"{r:02X}{g:02X}{b:02X}" # 创建新工作簿 wb = Workbook() ws = wb.active # 设置同 RGB 颜色 colors = [ (255, 200, 0), # 金色 (100, 149, 237), # 蓝色 (220, 20, 60) # 红色 ] for i, rgb in enumerate(colors, start=1): cell = ws.cell(row=i, column=1) cell.value = f"RGB{rgb}" cell.fill = PatternFill( fill_type="solid", fgColor=rgb_to_hex(*rgb) # 解包 RGB 元组 ) wb.save("彩色单元格.xlsx") ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值