Given this dataframe:
import pandas as pd
df = pd.DataFrame({'Grade':[2,3,4,5], 'start':[0,0,20,10], 'end':[100,90,80,100]})
Grade start end
0 2 0 100
1 3 0 90
2 4 20 80
3 5 10 100
I would like to generate a table with it via plottable library with 2 columns: Grade and a column called "Progress" with bars (though a green arrow would be amazing) that starts at 'start' and ends at 'end' where the x-axis starts at 0 and ends at 100. Both 'start' and 'end should be annotated.
Here's an example of what I'm looking for in that column:
If "Start" starts beyond 0, then the bar (or arrow) should start at that relativel position on the "x-axis". The annotations should alwasy be on the left and right sides fo the bars (arrows), as in the example above.
From the "docs", I did find this example for bar charts:
ColumnDefinition(
"D",
width=1.25,
plot_fn=bar,
plot_kw={
"cmap": cmap,
"plot_bg_bar": True,
"annotate": True,
"height": 0.5,
"lw": 0.5,
"formatter": decimal_to_percent,
"xlim":[low, high],
},
),
...but I cannot find any reference to control the annotations in terms of labels and positions. I found that I can add "xlim" to the plot_kws but now I need to get start and end from the passed dataframe to determine those values per row.
import matplotlib.pyplot as plt
grades = '2 3 4 5'.split()
starts = [0,0,20,10]
ends = [100,90,80,100]
fig, ax= plt.subplots(layout='constrained')
ax.axis('off')
t = plt.table(
cellText=list(zip(grades, ['']*4)),
colLabels=['Grade', 'Progress'],
colWidths=[0.2, 0.3],
cellLoc='center',
loc='center',
edges='',
)
# apparently this is necessary to have the cells initialized
fig.canvas.draw()
trax = ax.transAxes
for row in range(1, 5):
cell = t[row, 1]
plt.plot((c._x0, c._x0+c._width), (c._y0+0.01, c._y0+0.01),
lw=0.3, color='black', transform=trax)
startx = c._x0+c._width*starts[row-1]/100
dx = c._width*(ends[row-1]-starts[row-1])/100
plt.arrow(startx, c._y0+0.0225, dx, 0.0,
color='forestgreen', width=0.006,
length_includes_head=True, transform=trax)
plt.show()