df.style is not working in pydroid3, a python IDE for Android mobile

74 Views Asked by At

I'm trying to highlight largest value in each column of my DataFrame. It's working well in my laptop but not in my pydroid3 mobile app...

data = {'Column1': [10, 15, 8],
    'Column2': [20, 5, 12],
   'Column3': [7, 18, 9]}

df = pd.DataFrame(data)
#print(df)

I tried as ...

df_styled = df.style.highlight_max(color='lightgreen')

print(df_styled)

Here I'm getting following as output...

<pandas.io.formats.style.Styler object at 0x76f9790520>

What does it mean and how can I get df.style on my Android app ??

1

There are 1 best solutions below

4
Marijn On BEST ANSWER

The output of Styler objects is visible in a Notebook (for example in Jupyter Lab or Google Colaboratory) because Notebooks have special handling for Pandas objects. If you run the code in regular Python (i.e., directly in the terminal) on a laptop or desktop computer then you get just the name of the object and no graphical output. Pydroid 3 works like a terminal, and displays only the textual output.

If you do want to show the table with colors, then there may be some options. The Styler class has functions to export the object in four different formats: plain text, html, LaTeX, and xlsx.

The plain text export removes the colors, so this is not suitable. The LaTeX export might be an option, but it is complicated (it would require sending the LaTeX code somewhere to be compiled, retrieving and possibly converting the result and showing it in the app) and the basic export function does not handle the colors well (i.e., it does not produce valid LaTeX by default, this may be customizable). The Excel export preserves the colors, but it is probably not very convenient to display the result in an app - unless this is standalone output that you want to offer to the user for download, then it can be a nice option.

The remaining option is html output. Depending on how the app is designed it may be feasible to either show the rendered html directly or in a (possibly headless) browser window, or to convert the html in the background to an image and show that image.

Code:

import pandas as pd
data = {'Column1': [10, 15, 8],
     'Column2': [20, 5, 12],
    'Column3': [7, 18, 9]}

df = pd.DataFrame(data)

df_styled = df.style.highlight_max(color='lightgreen')

print(df_styled.to_string())
print(df_styled.to_html())
print(df_styled.to_latex())
df_styled.to_excel('cellcolors.xlsx')

Output:

 Column1 Column2 Column3
0 10 20 7
1 15 5 18
2 8 12 9
<style type="text/css">
#T_15e79_row0_col1, #T_15e79_row1_col0, #T_15e79_row1_col2 {
  background-color: lightgreen;
}
</style>
<table id="T_15e79">
  <thead>
    <tr>
      <th class="blank level0" >&nbsp;</th>
      <th id="T_15e79_level0_col0" class="col_heading level0 col0" >Column1</th>
      <th id="T_15e79_level0_col1" class="col_heading level0 col1" >Column2</th>
      <th id="T_15e79_level0_col2" class="col_heading level0 col2" >Column3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th id="T_15e79_level0_row0" class="row_heading level0 row0" >0</th>
      <td id="T_15e79_row0_col0" class="data row0 col0" >10</td>
      <td id="T_15e79_row0_col1" class="data row0 col1" >20</td>
      <td id="T_15e79_row0_col2" class="data row0 col2" >7</td>
    </tr>
    <tr>
      <th id="T_15e79_level0_row1" class="row_heading level0 row1" >1</th>
      <td id="T_15e79_row1_col0" class="data row1 col0" >15</td>
      <td id="T_15e79_row1_col1" class="data row1 col1" >5</td>
      <td id="T_15e79_row1_col2" class="data row1 col2" >18</td>
    </tr>
    <tr>
      <th id="T_15e79_level0_row2" class="row_heading level0 row2" >2</th>
      <td id="T_15e79_row2_col0" class="data row2 col0" >8</td>
      <td id="T_15e79_row2_col1" class="data row2 col1" >12</td>
      <td id="T_15e79_row2_col2" class="data row2 col2" >9</td>
    </tr>
  </tbody>
</table>
\begin{tabular}{lrrr}
 & Column1 & Column2 & Column3 \\
0 & 10 & \background-colorlightgreen 20 & 7 \\
1 & \background-colorlightgreen 15 & 5 & \background-colorlightgreen 18 \\
2 & 8 & 12 & 9 \\
\end{tabular}

Another alternative is to render the table through Matplotlib. Pydroid supports graphical output from this library out of the box. Matplotlib has a function to plot a dataframe as a table, so this is rather easy. Unfortunately Matplotlib does not support Styler objects, so you need to do the styling yourself. Code:

import pandas as pd
import matplotlib.pyplot as plt
data = {'Column1': [10, 15, 8],
     'Column2': [20, 5, 12],
    'Column3': [7, 18, 9]}

df = pd.DataFrame(data)

fig, ax = plt.subplots()

# hide axes
fig.patch.set_visible(False)
ax.axis('off')
ax.axis('tight')

# create color arrays for each row
# check for each value in a row if that is the maximum in the column
colors_max = []
dfmax = df.max()
for i in range(len(df.index)):
  colors_max.append([])
  for j in range(len(df.columns)):
    if df.loc[i][j] == dfmax[j]:
      colors_max[i].append('lightgreen')
    else:
      # odd rows get a white background,
      # even rows get a grey (whitesmoke) background
      if i% 2 == 0:
        colors_max[i].append('whitesmoke')
      else:
        colors_max[i].append('white')
# print the row colors for illustration purposes  
print(colors_max[i])


mytable = ax.table(cellText=df.values, colLabels=df.columns, loc='left', cellColours=colors_max, rowLabels=range(len(df.columns)))

# remove cell borders
for c in mytable.get_children():
    c.set_edgecolor('none')
# increase size
mytable.scale(1.1, 4)
# show the table as graphical output
plt.show()

# show original styled output as comparison
df_styled = df.style.highlight_max(color='lightgreen')

df_styled

The following output is from a Notebook for comparison, but the Matplotlib part works on Pydroid 3 as well.

enter image description here