Due to the current implementation in version 0.12.2 of the setRowColors function, the rows parameter must be passed a list of values:
import tkinter as tk
import pandas as pd
from pandastable import Table
root = tk.Tk()
frame = tk.Frame(root)
frame.pack(fill="both", expand=True)
df = pd.DataFrame()
df["column1"] = [1, 2, 3]
df["column2"] = ["a", "b", "c"]
pt = Table(frame, dataframe=df)
# rows=list of values
pt.setRowColors(rows=[1], clr='#ff3300', cols="all")
# No need to redraw it is done within the setRowColors function
pt.show()
root.mainloop()

There is an open issue for this on github Setting colour of cell in dataframe
The reason this happens is because of the way that the index is subset, and the way that Series.at modifies column dtypes depending on if it is accessing a cell or a group of cells.
This pandas code reproduces the error:
import numpy as np
import pandas as pd
df = pd.DataFrame({"column1": [1, 2, 3], "column2": ["a", "b", "c"]})
rc = pd.DataFrame()
rc['column1'] = pd.Series(np.nan, index=df.index)
idx = df.index[1] # <- uses int
print(idx) # 1 # (python int)
rc.at[idx, 'column1'] = '#ff3300'
print(rc)
Producing:
ValueError: could not convert string to float: '#ff3300'
However the following works as expected:
import numpy as np
import pandas as pd
df = pd.DataFrame({"column1": [1, 2, 3], "column2": ["a", "b", "c"]})
rc = pd.DataFrame()
rc['column1'] = pd.Series(np.nan, index=df.index)
idx = df.index[[1]] # <- uses list
print(idx) # Int64Index([1], dtype='int64') # (pandas Index object)
rc.at[idx, 'column1'] = '#ff3300'
print(rc)
column1
0 NaN
1 #ff3300
2 NaN
This occurs in the setRowColors function in version 0.12.2 source code:
def setRowColors(self, rows=None, clr=None, cols=None):
"""Set rows color from menu.
Args:
rows: row numbers to be colored
clr: color in hex
cols: column numbers, can also use 'all'
"""
if clr is None:
clr = pickColor(self, '#dcf1fc')
if clr == None:
return
if rows == None:
rows = self.multiplerowlist
df = self.model.df
idx = df.index[rows] # <- The issue is here (idx becomes an int if not a list)
rc = self.rowcolors
if cols is None:
cols = self.multiplecollist
elif cols is 'all':
cols = range(len(df.columns))
colnames = df.columns[cols]
for c in colnames:
if c not in rc.columns:
rc[c] = pd.Series(np.nan, index=df.index)
# rc[c][idx] = clr
rc.at[idx, c] = clr
self.redraw()
return
*Comment marking the line at issue is added for clarity