[Python] How to draw vertical dashed lines at the last non-NaN value for each sublist in plot?

Discussão em 'Python' iniciado por Stack, Julho 29, 2025.

  1. Stack

    Stack Membro Participativo

    I have a flat_list of values that I split into sublists of equal size D for a set of patients. Each patient's data is plotted over time (days), and I want to draw a vertical dashed line in the same color as the patient's curve at the last non-NaN x-position of each sublist. The dashed lines should extend from a global y_min - offset to y_max + offset.

    Here's a minimal example:

    import matplotlib.pyplot as plt
    import numpy as np

    def plot_app_efficiency(flat_list, D, P):
    if len(flat_list) % D != 0:
    raise ValueError("The length of the list must be a multiple of D.")

    # Split data for each patient
    patient_data = {}
    for idx, p_id in enumerate(P):
    start_idx = idx * D
    end_idx = (idx + 1) * D
    patient_data[p_id] = flat_list[start_idx:end_idx]

    # X-axis: days from 1 to D
    days = list(range(1, D + 1))

    # Create plot
    fig, ax = plt.subplots(figsize=(10, 6))

    # Calculate global y_min and y_max across all patients
    all_values = np.concatenate([np.array(values) for values in patient_data.values()])
    y_min = np.nanmin(all_values)
    y_max = np.nanmax(all_values)

    for patient, values in patient_data.items():
    values = np.array(values)
    line, = ax.plot(days, values, label=f'Patient {patient}', marker='o')

    # Find the last valid (non-NaN) value
    valid_indices = np.where(~np.isnan(values))[0]
    if len(valid_indices) > 0:
    last_valid_index = valid_indices[-1]
    x_val = days[last_valid_index]


    # Axis labels and title
    ax.set_xlabel('Days (D)')
    ax.set_ylabel('Value')
    ax.set_title('Values per patient over days')

    # Remove grid
    ax.grid(False)

    # Horizontal legend below the plot
    ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15),
    fancybox=True, shadow=False, ncol=len(P))

    plt.tight_layout()
    plt.show()

    #Example Call
    a= [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 0.3, 0.3, 0.3, 0.3, 0.4, 0.4, 0.4, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 0.3, 0.3, 0.3, 0.3, 0.3, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]
    b=40
    c=[1,2,3]
    plot_app_efficiency(a, b, c)


    This is what it should look like (sorry for the bad drawing):

    Picture

    Continue reading...

Compartilhe esta Página