Python的XLSX Writer库- 使用数字作为中点的三色刻度。

8
我正在尝试使用XLSX Writer进行条件格式设置,使用三色比例尺并将0中点值放在中间。 我希望所有负数从红色(最低数字)到黄色(当值为零时)进行缩放,而所有正数则从黄色(在零处)到绿色(在最高处)进行缩放。
当我尝试以下操作时,缩放会混乱。
在Excel中,它看起来像以下内容:

enter image description here

我可以弄清楚如何在XLSX编写器中进行3种颜色的比例,但似乎没有一个选项(我能看到的)使中点成为一个数字:
worksheet.conditional_format('G2:G83', {'type': '3_color_scale',
                                     'min_color': "red",
                                     'mid_color': "yellow",
                                     'max_color': "green"})

我接着尝试使用一个标准来区分数值大于零和小于零的情况

worksheet.conditional_format('G2:G83', {'type': '2_color_scale',
                                    'criteria': '<',
                                    'value': 0,
                                    'min_color': "red",
                                    'max_color': "yellow"})


worksheet.conditional_format('G2:G83', {'type': '2_color_scale',
                                    'criteria': '>',
                                    'value': 0,
                                     'min_color': "yellow",
                                     'max_color': "green"})

但似乎那也不起作用 - 如果有任何想法..请告诉我..非常感激。

完整的示例代码:

import xlsxwriter

workbook = xlsxwriter.Workbook('conditional_format.xlsx')
worksheet1 = workbook.add_worksheet()


# Add a format. Light red fill with dark red text.
format1 = workbook.add_format({'bg_color': '#FFC7CE',
                           'font_color': '#9C0006'})

# Add a format. Green fill with dark green text.
format2 = workbook.add_format({'bg_color': '#C6EFCE',
                           'font_color': '#006100'})

# Some sample data to run the conditional formatting against.
data = [
[34, 72, -38, 30, 75, 48, 75, 66, 84, 86],
[-6, -24, 1, -84, 54, 62, 60, 3, 26, 59],
[-28, 0, 0, 13, -85, 93, 93, 22, 5, 14],
[27, -71, -40, 17, 18, 79, 90, 93, 29, 47],
[0, 25, -33, -23, 0, 1, 59, 79, 47, 36],
[-24, 100, 20, 88, 29, 33, 38, 54, 54, 88],
[6, -57, -88, 0, 10, 26, 37, 7, 41, 48],
[-52, 78, 1, -96, 26, -45, 47, 33, 96, 36],
[60, -54, -81, 66, 81, 90, 80, 93, 12, 55],
[-70, 5, 46, 14, 71, -19, 66, 36, 41, 21],

]

for row, row_data in enumerate(data):
    worksheet1.write_row(row + 2, 1, row_data)


worksheet1.conditional_format('B2:B12', {'type': '2_color_scale',
                                    'criteria': '<',
                                    'value': 0,
                                    'min_color': "red",
                                    'max_color': "yellow"})


worksheet1.conditional_format('C2:C12', {'type': '2_color_scale',
                                    'criteria': '>',
                                    'value': 0,
                                     'min_color': "yellow",
                                     'max_color': "green"})

worksheet1.conditional_format('C2:C12', {'type': '2_color_scale',
                                    'criteria': '<',
                                    'value': 0,
                                     'min_color': "red",
                                     'max_color': "yellow"})


worksheet1.conditional_format('D2:D12', {'type': '3_color_scale',
                                     'min_color': "red",
                                     'mid_color': "yellow",
                                     'max_color': "green"})







workbook.close()    
writer.save()

这就是我得到的:

enter image description here

正如您所见,B列(第一列)没有绿色

C列没有红色

D列的值为0,表示绿色

有什么想法可以实现三步缩放并将零放在中间吗?

谢谢

2个回答

9
我可以解决如何在XLSX writer中使用3种颜色的比例尺,但似乎没有选项(我能看到的)可以使中点成为一个数字:
您可以使用min_typemid_typemax_type参数来设置以下类型:
min        (for min_type only)
num
percent
percentile
formula
max        (for max_type only)

请参考条件格式选项

因此,在您的情况下,应该是这样的。

worksheet1.conditional_format('D2:D12', {'type': '3_color_scale',
                                         'min_color': "red",
                                         'mid_color': "yellow",
                                         'max_color': "green",
                                         'mid_type': "num"})

然而,我不确定这是否能解决您的整体问题。可以将此添加到您的示例中,如果没有效果,则可以打开第二个问题。

您需要先弄清楚如何在Excel中实现您想要的内容。之后,在XlsxWriter中确定所需的内容通常会更容易一些。


干得好。我发现文档中可能的类型(最小值、数字、百分比等)很难找到。你的回复非常有帮助! - yeamusic21
1
如果我没有写文档的话,那会是一种赞美。;-) - jmcnamara
谢谢。如果我没有写文档的话,那会是个夸奖。:-| - jmcnamara

7

我知道这是一个老问题,但我最近遇到了这个问题,并想出了解决方法。

以下是我为我的工作编写的实用函数副本。主要问题在于min、mid和max类型都需要为“num”,并且它们需要为这些点指定值。

如果您只将mid类型设置为“num”并将值设置为0,则3种颜色比例尺仍将使用min和max作为端点。这意味着,如果列的内容全部在枢轴点的一侧,则着色实际上会忽略枢轴。

from xlsxwriter.utility import xl_col_to_name as index_to_col

MIN_MIN_FORMAT_VALUE = -500
MAX_MAX_FORMAT_VALUE = 500

def conditional_color_column(
        worksheet, df, column_name, min_format_value=None, pivot_value=0, max_format_value=None):
    """
    Do a 3 color conditional format on the column.

    The default behavior for the min and max values is to take the min and max values of each column, unless said value
    is greater than or less than the pivot value respectively at which point the values MIN_MIN_FORMAT_VALUE and
    MAX_MAX_FORMAT_VALUE are used. Also, if the min and max vales are less than or greater than respectively of
    MIN_MIN_FORMAT_VALUE and MAX_MAX_FORMAT_VALUE then the latter will be used

    :param worksheet: The worksheet on which to do the conditional formatting
    :param df: The DataFrame that was used to create the worksheet
    :param column_name: The column to format
    :param min_format_value: The value below which all cells will have the same red color
    :param pivot_value: The pivot point, values less than this number will gradient to red, values greater will gradient to green
    :param max_format_value: The value above which all cells will have the same green color
    :return: Nothing
    """
    column = df[column_name]
    min_value = min(column)
    max_value = max(column)

    last_column = len(df.index)+1
    column_index = df.columns.get_loc(column_name)
    excel_column = index_to_col(column_index)
    column_to_format = f'{excel_column}2:{excel_column}{last_column}'

    if min_format_value is None:
        min_format_value = max(min_value, MIN_MIN_FORMAT_VALUE)\
            if min_value < pivot_value else MIN_MIN_FORMAT_VALUE

    if max_format_value is None:
        max_format_value = min(max_value, MAX_MAX_FORMAT_VALUE)\
            if max_value > pivot_value else MAX_MAX_FORMAT_VALUE

    color_format = {
        'type': '3_color_scale',
        'min_type': 'num',
        'min_value': min_format_value,
        'mid_type': 'num',
        'mid_value': pivot_value,
        'max_type': 'num',
        'max_value': max_format_value
    }
    worksheet.conditional_format(column_to_format, color_format)

非常感谢!这并不明显。如果您传递一个数字,Pythonic 的做法是从传递的数据类型中识别它。但 Excel 不是 Pythonic 的,所以我很感激您帮助我解决了同样的问题。 - Marc Maxmeister

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接