painting a cell in excel with condition using python - python

I am creating an excel report that should give me a result of automatic tests. It should say if they failed/ passed.
I have created the excel report from csv using this code:
import pandas as pd
import string
writer = pd.ExcelWriter("file.xlsx", engine="xlsxwriter")
df = pd.read_csv("K:\\results.csv")
df.to_excel(writer, sheet_name=os.path.basename("K:\\results.csv"))
# skip 2 rows
df.to_excel(writer, sheet_name='Sheet1', startrow=2, header=False, index=False)
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Add a header format.
header_format = workbook.add_format({
'bold': True,
'fg_color': '#ffcccc',
'border': 1})
# create dictionary for map length of columns
d = dict(zip(range(25), string.ascii_uppercase))
print (d)
max_len = d[len(df.columns) - 1]
print(max_len)
# C
# dynamically set merged columns in first row
worksheet.merge_range('A1:' + max_len + '1', 'This Sheet is for Personal Details')
for col_num, value in enumerate(df.columns.values):
# write to second row
worksheet.write(1, col_num, value, header_format)
column_len = df[value].astype(str).str.len().max()
column_len = max(column_len, len(value)) + 3
worksheet.set_column(col_num, col_num, column_len)
writer.save()
Now, if i have a cell that has the word" success" in it, i want to color it green, and if i have a cell in the excel which says "fail" in it i want to color it red. How can i access a specific cell in the excel file with the condition of whats written in it?
Thanks.

You could use a conditional format for this:
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Data': ['success', 'bar', 'fail', 'foo', 'success']})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('pandas_conditional.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Add a format for fail. Light red fill with dark red text.
fail_format = workbook.add_format({'bg_color': '#FFC7CE',
'font_color': '#9C0006'})
# Add a format for pass. Green fill with dark green text.
pass_format = workbook.add_format({'bg_color': '#C6EFCE',
'font_color': '#006100'})
# Apply conditional formats to the cell range.
worksheet.conditional_format('B2:B6', {'type': 'text',
'criteria': 'containing',
'value': 'fail',
'format': fail_format})
worksheet.conditional_format('B2:B6', {'type': 'text',
'criteria': 'containing',
'value': 'success',
'format': pass_format})
# Close the Pandas Excel writer and output the Excel file.
writer.save()
Output:
See the XlsxWriter docs on Working with Conditional Formatting. Note, you can also use a numerical (row, col) range instead of the A1:D4 range, see the conditional_format().

Related

How do I map a color dataframe onto an ExcelWriter sheet

I want to map colors onto a dataframe and then output as an ExcelWriter worksheet. I don't want to use a dictionary as some values in the sheet require different colors depending on their position. My code is as follows:
import pandas as pd
import xlsxwriter
#my worksheet
tab = pd.DataFrame([['C','T','G'],['C','G','G'],['A','T','G']])
#color map
colors = pd.DataFrame([['orange','b','b'],['b','orange','orange'],['b','b','orange']])
writer = pd.ExcelWriter("file.xlsx", engine='xlsxwriter')
tab.to_excel(writer, sheet_name='Sheet1', index=False)
workbook = writer.book
worksheet = writer.sheets['Sheet1']
txt = 'A2:C4'
#PROBLEMS START HERE
colorsfmt = workbook.add_format({'bg_color': colors})
worksheet.conditional_format(txt, {'type': 'cell',
'criteria': '=',
'value': "I DON'T KNOW",
'format': "I DON'T KNOW"})
writer.save()
Just to clarify, the first row of the XL sheet would read C T G and have background colors orange, blue, blue. It's DNA codes - they're colored according to rarity along columns (rather than by individual code values - which is why I can't use a dictionary)

Python - Function that adjusts columns and colors cells in multiple spread sheets

Hello everyone hope you all are doing well.
Currently, I have a project I am working on that deals with a lot of data and I'm creating numerous pandas DataFrames with all the data I have and trying to compile it all into an excel file with each DataFrame having its own excel sheet. What I want to do is create a function that automatically adds each sheet to the excel file, expands the columns in each sheet, and colors cells in each sheet accordingly.
For example...
sheet14 would look something like what is attached...
Each sheet looks just like this but could have various amounts of rows but always the same amount of columns.
What I want to do is color the cells of Col1 that have a length of 1 green, length of 3 yellow, length of 5 purple, and so on.
How am I able to do this? I am able to do this with one sheet easily but to automate it is tedious because the multiple sheets part is making it difficult for me since I never had to deal with that.
Just so you know, cycled_data_aggregate looks like,
[DataFrame, 'A', 'A']
It is a <class 'list'> which contains,
[<class 'pandas.core.frame.DataFrame'>, <class 'str'>, <class 'str'>]
Thank you all so much if you help! Hope I explained everything well enough. If not just a general explanation would help as the code I made is pretty weird likely haha! :)
import pandas as pd
import openpyxl
from openpyxl.styles import Color, PatternFill, Font, Border, Side
import xlsxwriter
from xlsxwriter.utility import xl_rowcol_to_cell
out_path = "C:\\....\\....xlsx"
writer1 = pd.ExcelWriter(out_path)
def MultipleSheetAdder(cycled_data_aggregate, overwrite_sheet_name, true_false):
# If the function for cycled_data_aggregate returns None...
if cycled_data_aggregate == None:
return None
# The sheet's data
cycled_data = cycled_data_aggregate[0]
# If you want to overwrite what the sheet name is called and not use the
# cycled_data_aggregate's returned data
if true_false:
sheet_name = overwrite_sheet_name
else:
sheet_name = cycled_data_aggregate[1]
cycled_data.to_excel(writer, sheet_name=sheet_name)
for column in cycled_data:
column_length = max(cycled_data[column].astype(str).map(len).max(), len(column)) + 3
col_idx = cycled_data.columns.get_loc(column)
writer.sheets[sheet_name].set_column(col_idx, col_idx, column_length)
# Add section here to change colors of specific rows in the first two columns depending on what
# values they are.
{INSERT CODE HERE}
return None # Does this function need to even return anything?
MultipleSheetAdder(Function(raw_data), '', False)
writer1.save()
One way to add the colours is with conditional formatting. Here is an example based on your data:
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Col1': ['1.2.4', '2.2', '1.2.2', '2', '1.7.4'],
'Col2': [200, 100, 130, 140, 300],
'Col3': ['Text 1', 'Text 2', 'Text 3', 'Text 4', 'Text 5']})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('pandas_conditional.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1', index=False)
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
format1 = workbook.add_format({'bg_color': 'green'})
format2 = workbook.add_format({'bg_color': 'yellow'})
format3 = workbook.add_format({'bg_color': 'purple'})
# Apply a conditional format to the cell range.
max_row = df.shape[0]
worksheet.conditional_format(1, 0, max_row, 0, {'type': 'formula',
'criteria': '=LEN($A2)=1',
'format': format1})
worksheet.conditional_format(1, 0, max_row, 0, {'type': 'formula',
'criteria': '=LEN($A2)=3',
'format': format2})
worksheet.conditional_format(1, 0, max_row, 0, {'type': 'formula',
'criteria': '=LEN($A2)=5',
'format': format3})
# Close the Pandas Excel writer and output the Excel file.
writer.save()
Output:

conditional formatting python dataframe column values with different colors

I am trying to color values of one column in my df based on its values. I tried with only one value but I don't get any colored result. Here is my code
writer = pd.ExcelWriter('resultcolored.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet')
workbook = writer.book
worksheet = writer.sheets["Sheet"]
format = workbook.add_format({'bg_color': '#C6EFCE',
'font_color': '#006100'})
worksheet.conditional_format( 'AJ1:AJ10',
{ 'type': 'text',
'criteria': 'containing',
'value': 'Direct',
'format': format
}
)
writer.save()
It saves the file, but doesn't colot any of the values. Can you please help me out?
It should work as expected. Here is a working example based in your code:
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Data': ['Foo', 'Director', 'bar', 'Directory', 'Baz']})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('pandas_conditional.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
format = workbook.add_format({'bg_color': '#C6EFCE',
'font_color': '#006100'})
# Apply a conditional format to the cell range.
worksheet.conditional_format( 'B2:B6',
{ 'type': 'text',
'criteria': 'containing',
'value': 'Direct',
'format': format
}
)
writer.save()
Output:

How to apply Format object to index values in pandas

Question: I have a data frame with column names with respective values. But when i apply format object to column headings, they are not responding.
Code:
import pandas as pd
root = "C:\Users\543904\Desktop\New folder\"
dict = {'name':["aparna", "pankaj"],
'degree': ["MBA", "BCA"],
'score':[90, 40]}
df = pd.DataFrame(dict)
writer = pd.ExcelWriter(root + 'output', engine = "xlsxwriter")
df.to_excel(writer, sheet_name='df', index = False)
workbook = writer.book
worksheet = writer.sheets['df']
Format_Object = workbook.add_format({'text_wrap': True})
Format_Object.set_bold()
Format_Object.set_align('center')
Format_Object.set_align('top')
Format_Object.set_border(1)
Format_Object.set_bg_color('#0ef0ce')
worksheet.set_row(0, 20, Format_Object)
writer.save()
expected:
Expected
Actual:
Actual
This is explained in the XlsxWriter docs on Working with Python Pandas and XlsxWriter:
Pandas writes the dataframe header with a default cell format. Since it is a cell format it cannot be overridden using set_row(). If you wish to use your own format for the headings then the best approach is to turn off the automatic header from Pandas and write your own. For example:
# Turn off the default header and skip one row to allow us to insert a
# user defined header.
df.to_excel(writer, sheet_name='Sheet1', startrow=1, header=False)
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Add a header format.
header_format = workbook.add_format({
'bold': True,
'text_wrap': True,
'valign': 'top',
'fg_color': '#D7E4BC',
'border': 1})
# Write the column headers with the defined format.
for col_num, value in enumerate(df.columns.values):
worksheet.write(0, col_num + 1, value, header_format)

Format entire row with conditional_format using pandas xlswriter module

I am creating an excel report using pandas xlswriter module. Below the code-snippet for the same.
number_rows = len(df.index)
//df is dataframe
writer = pd.ExcelWriter("Report_1.xlsx",engine='xlsxwriter')
df.to_excel(writer,"report")
workbook = writer.book
worksheet = writer.sheets['report']
# Define range for the color formatting
color_range = "A2:F{}".format(number_rows+1)
format1 = workbook.add_format({'bg_color': '#FFC7CE',
'font_color': '#9C0006'})
worksheet.conditional_format(color_range, {'type': 'text',
'criteria' : 'containing',
'value': 'SUCCESS',
'format': format1})
I want to highlight a row ('bg_color': '#FFC7CE', 'font_color': '#9C0006') based on a cell value(=SUCCESS). But when I use the "conditional_format" it is applying only on that particular cell. Is there any way to apply the format to the entire row if the “criteria” matches cell value?
I've provided a fully reproducible example below that makes use of the INDIRECT() function from Excel (Link here). Please note that I've set the range as $A$1:$B$6 but you can extend this to a different range if you have more columns.
import pandas as pd
df = pd.DataFrame({"Name": ['A', 'B', 'C', 'D', 'E'],
"Status": ['SUCCESS', 'FAIL', 'SUCCESS', 'FAIL', 'FAIL']})
number_rows = len(df.index) + 1
writer = pd.ExcelWriter('Report_1.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', index=False)
workbook = writer.book
worksheet = writer.sheets['Sheet1']
format1 = workbook.add_format({'bg_color': '#FFC7CE',
'font_color': '#9C0006'})
worksheet.conditional_format("$A$1:$B$%d" % (number_rows),
{"type": "formula",
"criteria": '=INDIRECT("B"&ROW())="SUCCESS"',
"format": format1
}
)
workbook.close()
with expected output in excel:

Categories