Creating our Table Writing Function
Creating our Table Writing Function¶
In case you have not seen it before, calling values with a DataFrame will return a numpy array of data and calling tolist() converts it to a nested list.
# Doing values.tolist() on a dataframe returns the following
print(yield_curve_table.reset_index().values.tolist())
[['1 Mo', 1.48, 2.44, -0.96, 0.03, 1.45], ['3 Mo', 1.55, 2.45, -0.9000000000000001, 0.04, 1.51], ['6 Mo', 1.6, 2.56, -0.96, 0.12, 1.48], ['1 Yr', 1.59, 2.63, -1.0399999999999998, 0.25, 1.34], ['2 Yr', 1.58, 2.48, -0.8999999999999999, 0.67, 0.91], ['3 Yr', 1.62, 2.46, -0.8399999999999999, 1.1, 0.52], ['5 Yr', 1.69, 2.51, -0.8199999999999998, 1.65, 0.04], ['7 Yr', 1.83, 2.59, -0.7599999999999998, 1.97, -0.1399999999999999], ['10 Yr', 1.92, 2.69, -0.77, 2.17, -0.25], ['20 Yr', 2.25, 2.87, -0.6200000000000001, 2.47, -0.2200000000000002], ['30 Yr', 2.39, 3.02, -0.6299999999999999, 2.75, -0.3599999999999999]]
Now that we know how to get the values out, we have everything we need to be able to create the function for writing the tables into the excel worksheet.
from openpyxl.worksheet.worksheet import Worksheet
from pandas import DataFrame
# Define a function to write a pandas dataframe to excel
def write_to_excel(ws: Worksheet, start_row: int,
start_column: int, df: DataFrame,
index: bool = True, columns: bool = True) -> None:
"""
Function which takes a worksheet and writes a table of data to it.
Parameters
----------
ws : Worksheet
The worksheet to modify
start_row : int
The row to begin on
start_column : int
The column to start on
df : DataFrame
The data to write
index : bool, optional
Whether to write the index labels. The default is True.
columns : bool, optional
Whether to write the column labels. The default is True.
"""
# If we want to include the index, reset the index on the dataframe first
if index:
write_data = df.reset_index().values.tolist()
else:
write_data = df.values.tolist()
# If we want to include columns we need to add the columns as the first in the nested lists
if columns:
# If we already added an index, then we are going to want also include a blank space since
# we don't want a label above the index
if index:
write_data = [[""]+list(df.columns)]+write_data
else:
write_data = [list(df.columns)]+write_data
# For every value iterate through finding the location to place it in
for row in range(len(write_data)):
for column in range(len(write_data[0])):
ws.cell(row=start_row+row,column=start_column+column).value = write_data[row][column]
wb = openpyxl.Workbook()
ws = wb.active
#Examples of writing to excel
write_to_excel(ws, 1, 1, yield_curve_table)
write_to_excel(ws, 16, 1, yield_curve_table,index=False)
write_to_excel(ws, 31, 1, yield_curve_table,columns=False)
write_to_excel(ws, 46, 1, yield_curve_table,index=False,columns=False)
wb.save("Workbooks/Example 2.xlsx")
Drawing Colors¶
We can change the colors in the workbook by using the attribute fill. We just need to get create a PatternFill object with the color we want.
from openpyxl.styles import PatternFill
# Create a workbook
wb = openpyxl.Workbook()
ws = wb.active
# Write the table in
write_to_excel(ws, 3, 1, yield_curve_table)
# PatternFill is a way to get colors, here we pass the start and end color as the same and use a fill type solid
# The color used here is red
my_fill_color = PatternFill(start_color='FF0000',
end_color='FF0000',
fill_type='solid')
# The fill attribute of a cell is the color to use
ws.cell(row=1,column=1).fill = my_fill_color
wb.save("Workbooks/Example 3.xlsx")
Red-Green Map¶
We want a function that takes a set of data and colors it red or green depending on if the value is negative or positive. For changes in the yield curve, this will make it much more readable to see the changes overall.
#Create a function to map red and green colors based on whether a field is positive or negative
def red_green_map(ws: Worksheet, df: DataFrame, start_row: int, start_column: int) -> None:
"""
Function which colors cells green or red depending on if
they are positive or negative
Parameters
----------
ws : Worksheet
The worksheet to modify
df : DataFrame
The dataframe of data
start_row : int
The row to start coloring on
start_column : int
The color to start coloring on
"""
# Get the values
write_data = df.values.tolist()
# Iterate over the rows and columns
for row in range(len(write_data)):
for column in range(len(write_data[0])):
# Set the fill color to green for positive numbers
if write_data[row][column] > 0:
fill = fill = PatternFill(start_color='008000',
end_color='008000',
fill_type='solid')
# Set the fill color to red for negative numbers
elif write_data[row][column] < 0:
fill = PatternFill(start_color='FF0000',
end_color='FF0000',
fill_type='solid')
# Change the color for the cell
ws.cell(row=start_row+row,column=start_column+column).fill = fill
# Create the excel workbook
wb = openpyxl.Workbook()
ws = wb.active
#Write the data to excel
write_to_excel(ws, 3, 1, yield_curve_table)
# We'll deal with only the two change columns
# So pass the data for only those and also pass their starting columns/rows
red_green_map(ws, yield_curve_table[["1 Year Change"]], 4, 4)
red_green_map(ws, yield_curve_table[["5 Year Change"]], 4, 6)
wb.save("Workbooks/Example 4.xlsx")
We finished some of the basic functionality we are going to want to use. Now we can write the function to wrap these functions up that should be used to fill out the treasury sheet.
#Put it all together for a function that takes a worksheet and yield curve data then writes the sheet
def write_treasury_sheet(ws: Worksheet, yield_curve_table: DataFrame):
"""
Function to fill out the treasury curve data
Parameters
----------
ws : Worksheet
The worksheet to modify
yield_curve_table : DataFrame
The yield curve data
"""
# Write the yield curve table
write_to_excel(ws, 3, 1, yield_curve_table)
# Color the yield curve changes red/green
red_green_map(ws, yield_curve_table[["1 Year Change"]], 4, 4)
red_green_map(ws, yield_curve_table[["5 Year Change"]], 4, 6)
wb = openpyxl.Workbook()
ws = wb.active
write_treasury_sheet(ws, yield_curve_table)
wb.save("Workbooks/Economic Report.xlsx")