Data is not getting displayed correctly when I use render dataframe

When i print the data, it is displayed correctly. But when I render it as a data frame, it is not.

@reactive.calc()
def display_conc():

 _,_,probe_conc,_,_,_,_ = getValues()
 burst_conc,gradual_conc,leak_conc = calculate_concentrations()

 return pd.DataFrame.from_dict(
    {"Burst": [100 * burst_conc / probe_conc, burst_conc],
     "Gradual": [100 * gradual_conc / probe_conc, gradual_conc],
     "Total": [100 * leak_conc / probe_conc, leak_conc]},
    columns=["Percentage (%)", "Concentration (pM)"],
    orient="index"
).round(2)

with ui.layout_columns(col_widths=[6,6,12]):
with ui.card(full_screen=True):
ui.card_header("Leakage")
@render.data_frame
def display_concentrations():
print(display_conc())
return display_conc()

Output:

Percentage (%) Concentration (pM)
Burst 0.40 4.02
Gradual -0.06 -0.60
Total 0.34 3.43

Can anyone help me figure out why there is a difference?

Quite a mystery. I find it intriguing that between these two calls:

Burst pM increases by a factor of 10, while the (%) stays the same, suggesting that burst_conc and probe_conc both get multiplied by 10.

Ordinarily, a reactive expression won't recalculate when called twice in a row, unless one of the reactive values it uses changes.

In these two lines, would getValues() depend on burst_conc, gradual_conc or leak_conc, or does calculate_concentrations() modify the value of probe_conc as a side-effect?

The other thing to check is whether it is the data table is receiving the correct values but displaying them incorrectly. To help check this, run the following experiments and report back with findings:

  1. Go straight to rendering the data table without printing anywhere else beforehand. Does it display the correct values in the data frame?:
@render.data_frame
def display_concentrations():
    return display_conc()
  1. Print the table a few times before displaying the data frame. Do the values changes in each print out?
@render.data_frame
def display_concentrations():
    print(display_conc())
    print(display_conc())
    print(display_conc())
    return display_conc()

Sorry, I copied the wrong ouput of the print statement. They're both same, it's just that the row header i.e., Burst, Gradual and Total is not getting displayed when i render it as a dataframe.

Percentage (%) Concentration (pM)
Burst 0.40 40.22
Gradual 2.12 211.60
Total 2.52 251.82

:man_facepalming:


Someone else also wanted to have row indexes appear in these tables too (see Index issues with render.table and render.data_frame · Issue #634 · posit-dev/py-shiny · GitHub) and the advice received was to simply convert the table index into a column of data using pandas.DataFrame.reset_index — pandas 2.2.2 documentation. In other words, adding .reset_index() to the data frame. Not my favourite solution, as I think the index should be kept apart from data, but it will get the index names to display.

Example app: Shiny editor

@render.data_frame
def display_concentrations():
        print(display_conc())
        return display_conc().reset_index(names="Description")
1 Like

Thank you! It worked :blush: