Skip to content
Advertisement

Python: How to plot Pabon Lasso chart using matplotlib?

I’m trying to plot a Pabon-Lasso chart using python’s matplotlib library. Pabon-Lasso is a healthcare services efficiency/performance plot. I only found the R code library for the plotting at: https://cran.r-project.org/web/packages/PabonLasso/index.html through searching but I have zero R knowledge.

Examples of a Pabon-Lasso chart is as follows:

enter image description here

enter image description here

The X-axis refers to BOR (Bed Occupancy Rate). The Y-axis refers to BTR (Bed Turnover Rate). The top and right-hand side axis represent the ALOS (Average Length of Stay).

The chart is divided into four quadrants with each representing different efficiencies/performance level. The horizontal line on the middle of the chart is the mean BTR. The vertical line on the middle of the chart is the mean BOR. The diagonal lines on the chart are at gradients of y/x = BTR/BOR. Each diagonal lines starts from origin. The intersection on the right(or top) axis represents the ALOS.

I have tried using the code below but stuck on the labelling for the top and right axis for ALOS parameter.

My code:

import matplotlib.pyplot as plt
import numpy as np

#[2016, 2017]
BOR=[57.6, 52.03]
BTR=[69.81, 20.08]
ALOS = [4.04, 12.68]

mean_BTR = np.mean(BTR)
mean_BOR = np.mean(BOR)

fig=plt.figure()
ax=fig.add_subplot(111, label="1")
ax2=fig.add_subplot(111, label="2", frame_on=False)

#scatter points
ax.scatter([0, 57.6], [0, 52.03], color="C0")
ax.annotate('2016', (57.6 + 2, 52.03))
ax.scatter([0, 69.81], [0, 20.08], color="C0")
ax.annotate('2017', (69.81 - 5, 20.08+2))

#draw diagonals
ax.axline((0, 0), (57.6, 52.03))
ax.axline((0, 0), (69.81, 20.08))

#draw quadrants/ mean BOR & BTR
ax.vlines(x=mean_BOR, ymin=0, ymax=np.max(BOR) + 20, color='b')
ax.hlines(y=mean_BTR, xmin=0, xmax=np.max(BTR) + 20, color='b')

ax.set_xlabel("BOR", color="C0")
ax.set_ylabel("BTR", color="C0")
ax.tick_params(axis='x', colors="C0")
ax.tick_params(axis='y', colors="C0")
ax.set_xlim(xmin=0, xmax=np.max(BTR) + 20)
ax.set_ylim(ymin=0, ymax=np.max(BOR) + 20)

ax2.xaxis.tick_top()
ax2.yaxis.tick_right()
ax2.set_xlabel('ALOS', color="C1") 
ax2.set_ylabel('ALOS', color="C1")       
ax2.xaxis.set_label_position('top') 
ax2.yaxis.set_label_position('right') 
ax2.tick_params(axis='x', colors="C1")
ax2.tick_params(axis='y', colors="C1")
ax2.axes.xaxis.set_ticks([])
ax2.axes.yaxis.set_ticks([])

plt.show()

enter image description here

Any help, please? Or are there any libraries already for this purpose. Thank you.

Advertisement

Answer

You are on the right track. The matplotlib.axes object has twinning methods that adds additional single axes.

For example:

import numpy as np
import matplotlib.pyplot as plt

#2016/2017
xmax, ymax = 100, 100
ALS = np.array([4.04, 12.68, 2])
BOR = [57.6, 69.81, 40]
BTR = [52.03, 20.08, 80]
annotations = [2016, 2017, 2018]
mean_BTR = np.mean(BTR)
mean_BOR = np.mean(BOR)

fig = plt.figure()
plot = fig.add_subplot()
plot.set_xlim(0, xmax)
plot.set_ylim(0, ymax)

# add lines
for x, y, label in zip(BOR, BTR, annotations):
    plot.axline((0, 0), (x, y))
    plot.scatter((0, x), (0, y))
    plot.annotate(label, (x - 10, y))
plot.vlines(x=mean_BOR, ymin=0, ymax=ymax, color='b')
plot.hlines(y=mean_BTR, xmin=0, xmax=xmax, color='b')

# add right axis ticks
right_axis = plot.twinx()
right_axis.set_ylim(0, ymax)
right_ticks = np.array([ymax * y / x for x, y in zip(BOR, BTR)])
right_axis.set_yticks(right_ticks[right_ticks <= ymax])
right_axis.set_yticklabels(ALS[right_ticks <= ymax])

# add top axis ticks
top_axis = plot.twiny()
top_axis.set_xlim(0, xmax)
top_ticks = np.array([xmax * x / y for x, y in zip(BOR, BTR)])
top_axis.set_xticks(top_ticks[top_ticks < xmax])
top_axis.set_xticklabels(ALS[top_ticks < xmax])

# add labels
plot.set_xlabel('BOR')
plot.set_ylabel('BTR', color='g')
right_axis.set_ylabel("ALOS")
top_axis.set_xlabel("ALOS")

plt.show()
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement