Search code examples
pythongoogle-sheetsgspread

How do I use gspread-formatting (or gspread) to change background color for entire columns?


Apologies, I do see similar questions. But, as far as I can tell, I am using the solutions posted there (I really have done my best to make sure I'm not wasting y'all's time)!

I am doing a bunch of analysis of political districts and am generating reports using Google Sheets.

So, after creating a dataframe and doing a million calculations, I go to save it to Google Sheets (which works, I can totally save it all), but I want to color the columns for the corresponding party.

My current code looks like this, and everything works except the coloring of the columns.

import pandas as pd
from matplotlib import colors
from gspread_formatting import *
def save_to_google_sheets(df,spreadsheet_name,worksheet_name,folder_id=None,coloring={}):
    """save dataframe worksheet"""
    # get spreadsheet and worksheet instances (open if they exist, create if they don't)
    ss,ws=get_worksheet(spreadsheet_name,worksheet_name,folder_id)
    # save dataframe to worksheet
    set_with_dataframe(ws,df,include_index=True,include_column_header=True,resize=True)
    # figure out how many rows each column will be
    num_rows=len(ws.get_values())
    # get which level of the pandas MultiIndex tells us the 'party'
    col_pty_lvl=df.columns.names.index('party') if 'party' in df.columns.names else None
    if col_pty_lvl:
        # get all parties in race
        parties=ws.row_values(col_pty_lvl+1)
        # color columns for each party included in dictionary
        pty_colors={'democratic':'blue','republican':'red'}
        for pty,clr in pty_colors.items():
            # get red, green, and blue values for given color
            # ex: r=1.0, g=0.0, b=0.0
            r,g,b,a=colors.to_rgba(clr)
            # get index of all columns belonging to this party
            pty_cols=[i for i,p in enumerate(parties) if p==pty]
            # set background color for each column
            for c in pty_cols:
                fmt=CellFormat(backgroundColor=Color(r,g,b),
                    horizontalAlignment='CENTER')
                # get A1 notation of column
                # sample output: 'B1:B93'
                a1=f'{gspread.utils.rowcol_to_a1(1,c)}:{gspread.utils.rowcol_to_a1(num_rows,c)}'
                format_cell_range(ws,a1,fmt)```

Solution

  • I change with [worksheet].format, maybe helpful:

    import gspread
    from oauth2client.service_account import ServiceAccountCredentials
       
    scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://spreadsheets.google.com/feeds']
    
    creds = ServiceAccountCredentials.from_json_keyfile_name("your json service account", scope)
    client = gspread.authorize(creds)
    spreadsheet = client.open_by_key("key of your spreadsheet")
    ws = spreadsheet.worksheet("workssheets name")
    # range, white background:
    ws.format("A1:E10", { 'backgroundColor': {
        'red':1.0,
        'green':1.0,
        'blue':1.0}})
    # entire columns, as RGB:
    ws.format("A:E", { 'backgroundColor': {
        'red':255/255,
        'green':255/255,
        'blue':255/255}})