title: How do I plot the time-series for each time-point treatment of each patient?
body: <p>I want to plot a time-series for each patient, where the substring after the first underscore <code>_</code> is the patient ID. I also want the time points in chronological order, meaning the substring prior to the first underscore <code>_</code> must be plotted in ascending order.</p>
  <pre><code>import plotly.express as px
  import numpy as np
  import pandas as pd
  
  # Treatment variables
  hours = treatment_info.columns + &quot;h&quot;
  patient_id = treatment_info.loc[&quot;Patient ID&quot;]
  time = treatment_info.loc[&quot;Time&quot;]
  time_cluster = treatment_info.loc['Time Cluster'].str.replace('Cluster ', 'TimeC') # TimeC = Time Cluster
  patient_id_cluster = treatment_info.loc[&quot;Patient ID Cluster&quot;].str.replace(&quot;Cluster &quot;, &quot;PIDC&quot;) # PIDC = Patient ID Cluster
  survival = treatment_info.loc[&quot;Survivor/Non-Survivor&quot;]
  
  # Append all the treatment variables to assign new column names for the treatment columns, separated with &quot;_&quot;
  treatment_col = hours + &quot;_&quot; +  patient_id + &quot;_&quot; + time + &quot;_&quot; + time_cluster + &quot;_&quot; + patient_id_cluster + &quot;_&quot; + survival
  
  # Controls
  
  pos_neg_ctl_df = df.loc[((df[&quot;mrna_assignment&quot;].str.contains(&quot;pos_control&quot;)) | (df[&quot;mrna_assignment&quot;].str.contains(&quot;neg_control&quot;))),:] 
  
  probe_ctl_df = df.loc[((df[&quot;category&quot;].str.contains(&quot;control-&gt;affx&quot;)) | (df[&quot;category&quot;].str.contains(&quot;control-&gt;bgp-&gt;antigenomic&quot;))),:] 
  </code></pre>
  <p>Here, for each patient <code>patient_id</code>, I want to find the difference in <code>hours</code> of treatment. All the patients in one plot.</p>
  <pre><code>for patient_id in hsp_treatment_df.index.split('_')[1]:
    for hours in hsp_treatment_df.index.split('_')[0]:
      fig = px.line(df, x=&quot;patient_id&quot;, y=&quot;Gene Expression&quot;, title=&quot;Time-Series Treatment Analysis for Each Patient&quot;)
      fig.show()
  </code></pre>
  <p>Traceback:</p>
  <pre><code>---------------------------------------------------------------------------
  AttributeError                            Traceback (most recent call last)
  &lt;ipython-input-93-1a74154283c4&gt; in &lt;module&gt;()
        2 ## Get the patient ID from each column
        3 
  ----&gt; 4 for patient_id in hsp_treatment_df.index.split('_')[1]:
        5   for hours in hsp_treatment_df.index.split('_')[0]:
        6     fig = px.line(df, x=&quot;patient_id&quot;, y=&quot;Gene Expression&quot;, title=&quot;Time-Series Treatment Analysis for Each Patient&quot;)
  
  AttributeError: 'Index' object has no attribute 'split'
  </code></pre>
  <p>Dataframe as dictionary:</p>
  <pre><code>hsp_treatment_df[1:3].to_dict()
  {'0h_P1_T1_TimeC1_PIDC4_Non-Survivor': {'DNAJC14': '8.44', 'DNAJC30': '7.34'},
   '0h_P2_T1_TimeC2_PIDC2_Survivor': {'DNAJC14': '8.34', 'DNAJC30': '7.42'},
   '0h_P3_T1_TimeC1_PIDC1_Survivor': {'DNAJC14': '8.67', 'DNAJC30': '7.15'},
   '0h_P4_T1_TimeC1_PIDC1_Survivor': {'DNAJC14': '8.63', 'DNAJC30': '7.46'},
   '0h_P5_T1_TimeC4_PIDC3_Survivor': {'DNAJC14': '8.32', 'DNAJC30': '7.29'},
   '12h_P1_T4_TimeC2_PIDC4_Non-Survivor': {'DNAJC14': '8.64', 'DNAJC30': '7.2'},
   '12h_P2_T4_TimeC3_PIDC2_Survivor': {'DNAJC14': '8.38', 'DNAJC30': '7.32'},
   '12h_P3_T4_TimeC2_PIDC1_Survivor': {'DNAJC14': '8.57', 'DNAJC30': '7.32'},
   '12h_P4_T4_TimeC2_PIDC2_Survivor': {'DNAJC14': '8.25', 'DNAJC30': '6.98'},
   '12h_P5_T4_TimeC2_PIDC3_Survivor': {'DNAJC14': '8.25', 'DNAJC30': '7.38'},
   '24h_P1_T5_TimeC4_PIDC4_Non-Survivor': {'DNAJC14': '8.43', 'DNAJC30': '7.41'},
   '24h_P2_T5_TimeC3_PIDC2_Survivor': {'DNAJC14': '8.54', 'DNAJC30': '7.26'},
   '24h_P3_T5_TimeC3_PIDC1_Survivor': {'DNAJC14': '8.42', 'DNAJC30': '7.25'},
   '24h_P4_T5_TimeC3_PIDC2_Survivor': {'DNAJC14': '8.6', 'DNAJC30': '6.93'},
   '24h_P5_T5_TimeC3_PIDC3_Survivor': {'DNAJC14': '8.14', 'DNAJC30': '7.52'},
   '48h_P1_T6_TimeC3_PIDC1_Non-Survivor': {'DNAJC14': '8.27', 'DNAJC30': '7.46'},
   '48h_P2_T6_TimeC3_PIDC3_Survivor': {'DNAJC14': '8.23', 'DNAJC30': '7.45'},
   '48h_P3_T6_TimeC3_PIDC1_Survivor': {'DNAJC14': '8.65', 'DNAJC30': '6.77'},
   '48h_P4_T6_TimeC3_PIDC2_Survivor': {'DNAJC14': '8.7', 'DNAJC30': '7.28'},
   '48h_P5_T6_TimeC3_PIDC3_Survivor': {'DNAJC14': '8.21', 'DNAJC30': '7.56'},
   '4h_P1_T2_TimeC1_PIDC4_Non-Survivor': {'DNAJC14': '8.69', 'DNAJC30': '7.53'},
   '4h_P2_T2_TimeC2_PIDC1_Survivor': {'DNAJC14': '8.47', 'DNAJC30': '7.41'},
   '4h_P3_T2_TimeC2_PIDC1_Survivor': {'DNAJC14': '8.38', 'DNAJC30': '7.29'},
   '4h_P5_T2_TimeC2_PIDC3_Survivor': {'DNAJC14': '8.1', 'DNAJC30': '7.47'},
   '8h_P1_T3_TimeC4_PIDC4_Non-Survivor': {'DNAJC14': '8.58', 'DNAJC30': '7.29'},
   '8h_P2_T3_TimeC2_PIDC2_Survivor': {'DNAJC14': '8.13', 'DNAJC30': '7.58'},
   '8h_P3_T3_TimeC4_PIDC1_Survivor': {'DNAJC14': '8.44', 'DNAJC30': '7.38'},
   '8h_P4_T3_TimeC4_PIDC1_Survivor': {'DNAJC14': '8.53', 'DNAJC30': '7.32'},
   '8h_P5_T3_TimeC4_PIDC3_Survivor': {'DNAJC14': '8.41', 'DNAJC30': '7.28'}}
  </code></pre>