import pandas as pd
import matplotlib.pyplot as plt
from dataclasses import dataclass
import os
import numpy as np
Reproduction
This notebook aims to reproduce Figure 3 from Anagnostou et al. 2022.
The run time for this notebook is a couple of seconds.
Set-up
Import required packages
Set file paths
@dataclass(frozen=True)
class Paths:
'''Singleton object for storing paths to data and database.'''
= '../output'
outputs = 'OUT_STATS.csv'
model = 'fig3.png'
figure
= Paths() paths
Run model
%run ./main.py -z ../input/ZONES.csv -p ../input/ICU_INPUT_PARAMS.csv -c ../input/DAILY_ARRIVALS.csv -o ../output/OUT_STATS.csv
Replication 1 out of 5
Replication 2 out of 5
Replication 3 out of 5
Replication 4 out of 5
Replication 5 out of 5
Import model results
= pd.read_csv(os.path.join(paths.outputs, paths.model))
data data.head()
day-mean | day-s | day-sd | day-ci | emArrivals-mean | emArrivals-s | emArrivals-sd | emArrivals-ci | elArrivals-mean | elArrivals-s | ... | zone7-available-sd | zone7-available-ci | zone8-type-mean | zone8-type-s | zone8-type-sd | zone8-type-ci | zone8-available-mean | zone8-available-s | zone8-available-sd | zone8-available-ci | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 | 10.8 | 48.8 | 3.492850 | 3.061618 | 3.8 | 30.8 | ... | 0.000000 | 0.000000 | 6.0 | 0.0 | 0.0 | 0.0 | 15.0 | 0.0 | 0.000000 | 0.000 |
1 | 1.0 | 0.0 | 0.0 | 0.0 | 6.6 | 29.2 | 2.701851 | 2.368277 | 6.0 | 6.0 | ... | 0.000000 | 0.000000 | 6.0 | 0.0 | 0.0 | 0.0 | 15.0 | 0.0 | 0.000000 | 0.000 |
2 | 2.0 | 0.0 | 0.0 | 0.0 | 8.8 | 82.8 | 4.549725 | 3.988010 | 5.8 | 6.8 | ... | 2.792848 | 2.448039 | 6.0 | 0.0 | 0.0 | 0.0 | 14.0 | 0.0 | 0.000000 | 0.000 |
3 | 3.0 | 0.0 | 0.0 | 0.0 | 5.4 | 83.2 | 4.560702 | 3.997631 | 4.0 | 26.0 | ... | 1.673320 | 1.466730 | 6.0 | 0.0 | 0.0 | 0.0 | 15.0 | 0.0 | 0.000000 | 0.000 |
4 | 4.0 | 0.0 | 0.0 | 0.0 | 4.6 | 57.2 | 3.781534 | 3.314661 | 4.2 | 14.8 | ... | 1.095445 | 0.960200 | 6.0 | 0.0 | 0.0 | 0.0 | 14.2 | 0.8 | 0.447214 | 0.392 |
5 rows × 144 columns
Create plot
def add_ci(x, y, error, ax, color, alpha):
'''
Add shaded confidence interval to a subplot
Parameters:
-----------
x : column
Column being plot on x axis
y : column
Column with mean values being plot on y axis
error : column
Column containing confidence interval for mean on each day
ax : matplotlib axis object
Axis to add confidence interval to
color : string
Color of shaded confidence interval
alpha : number between 0 and 1
Transparency of shaded confidence interval
'''
-error, y+error, color=color, alpha=alpha) ax.fill_between(x, y
# Set up number of subplots and figure size
= plt.subplots(3, 2, figsize=(15, 13))
fig, ax
# Mean lines
0,0].plot(data['el-capacity-mean'], color='black', marker='.',
ax[='Elective capacity mean')
label0,0].plot(data['el-available-mean'], color='green', marker='.',
ax[='Elective availability mean')
label1,0].plot(data['el-capacity-mean'], color='black',
ax[='Elective capacity mean')
label2,0].plot(data['el-available-mean'], color='green',
ax[='Elective availability mean')
label0,1].plot(data['c-capacity-mean'], color='black', marker='.',
ax[='COVID-19 capacity mean')
label0,1].plot(data['c-available-mean'], color='green', marker='.',
ax[='COVID-19 availability mean')
label1,1].plot(data['c-capacity-mean'], color='black',
ax[='COVID-19 capacity mean')
label2,1].plot(data['c-available-mean'], color='green',
ax[='COVID-19 availability mean')
label
# Add confidence intervals
'day-mean'], data['el-capacity-mean'], data['el-capacity-ci'],
add_ci(data[=ax[1,0], color='black', alpha=0.2)
ax'day-mean'], data['el-available-mean'], data['el-available-ci'],
add_ci(data[=ax[2,0], color='green', alpha=0.2)
ax'day-mean'], data['c-capacity-mean'], data['c-capacity-ci'],
add_ci(data[=ax[1,1], color='black', alpha=0.2)
ax'day-mean'], data['c-available-mean'], data['c-available-ci'],
add_ci(data[=ax[2,1], color='green', alpha=0.2)
ax
# Set tick frequency and axis limits for subplots
=np.arange(0,24), ylim=(0,12), yticks=np.arange(0,14,2))
plt.setp(ax, xticks1,1].set_ylim(0,14)
ax[1,1].set_yticks(np.arange(0, 16, 2))
ax[2,1].set_ylim(0,14)
ax[2,1].set_yticks(np.arange(0, 16, 2))
ax[
# Loop through the axis objects
= 0
i = ['a', 'd', 'b', 'e', 'c', 'f']
letter for ax in ax.flat:
# Add grid
True, alpha=0.2)
ax.grid(# Add X and Y axis labels
'Days')
ax.set_xlabel('Beds')
ax.set_ylabel(# Add a legend below the plot
=(0.7, -0.3))
ax.legend(bbox_to_anchor# Annotate with a) - f), only including in tight_layout() for first two
= ax.annotate(f'{letter[i]})', xy=(-0.09, 1.1),
an ='axes fraction', fontsize=13, weight='bold')
xycoordsif i >= 2:
False)
an.set_in_layout(+= 1
i
# Prevent overlap between subplots
plt.tight_layout()
# Save the figure
plt.savefig(os.path.join(paths.outputs, paths.figure))
plt.show()