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:
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()
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()