0

I have the following dataframe where it contains the best equipment in operation ranked by 1 to 300 (1 is the best, 300 is the worst) over a few days (df columns)

    Equipment         21-03-27  21-03-28    21-03-29    21-03-30    21-03-31    21-04-01    21-04-02 
P01-INV-1-1              1         1           1           1           1           2           2
P01-INV-1-2              2         2           4           4           5           1           1
P01-INV-1-3              4         4           3           5           6           10          10

I would like to customize a line plot (example found here) but I'm having some troubles trying to modify the example code provided:

import matplotlib.pyplot as plt
import numpy as np

def energy_rank(data, marker_width=0.1, color='blue'):
    y_data = np.repeat(data, 2)
    x_data = np.empty_like(y_data)
    x_data[0::2] = np.arange(1, len(data)+1) - (marker_width/2)
    x_data[1::2] = np.arange(1, len(data)+1) + (marker_width/2)
    lines = []
    lines.append(plt.Line2D(x_data, y_data, lw=1, linestyle='dashed', color=color))
    for x in range(0,len(data)*2, 2):
        lines.append(plt.Line2D(x_data[x:x+2], y_data[x:x+2], lw=2, linestyle='solid', color=color))
    return lines

data = ranks.head(4).to_numpy() #ranks is the above dataframe

artists = []
for row, color in zip(data, ('red','blue','green','magenta')):
    artists.extend(energy_rank(row, color=color))

fig, ax = plt.subplots()
ax.set_xticklabels(ranks.columns) # set X axis to be dataframe columns
ax.set_xticklabels(ax.get_xticklabels(), rotation=35, fontsize = 10)


for artist in artists:
    ax.add_artist(artist)
ax.set_ybound([15,0])
ax.set_xbound([.5,8.5])

When using ax.set_xticklabels(ranks.columns), for some reason, it only plots 5 of the 7 days from ranks columns, removing specifically the first and last values. I tried to duplicate those values but this did not work as well. I end up having this below:

enter image description here

In summary, I would like to know if its possible to do 3 customizations:

  1. input all dates from ranks columns on X axis
  2. revert Y axis. ax.set_ybound([15,0]) is not working. It would make more sense to see the graph starting with 0 on top, since 1 is the most important rank to look at
  3. add labels to the end of each line at the last day (last value on X axis). I could add the little window label, but it often gets really messy when you plot more data, so adding just the text at the end of each line would really make it look cleaner

Please let me know if those customizations are impossible to do and any help is really appreciated! Thank you in advance!

Pedro de Sá
  • 760
  • 6
  • 19

1 Answers1

1

To show all the dates, use plt.xticks() and set_xbound to start at 0. To reverse the y axis, use ax.set_ylim(ax.get_ylim()[::-1]). To set the legends the way you described, you can use annotation and set the coordinates of the annotation at your last datapoint for each series.

fig, ax = plt.subplots()
plt.xticks(np.arange(len(ranks.columns)), list(ranks.columns), rotation = 35, fontsize = 10)
plt.xlabel('Date')
plt.ylabel('Rank')

for artist in artists:
    ax.add_artist(artist)

ax.set_ybound([0,15])
ax.set_ylim(ax.get_ylim()[::-1])
ax.set_xbound([0,8.5])
ax.annotate('Series 1', xy =(7.1, 2), color = 'red')
ax.annotate('Series 2', xy =(7.1, 1), color = 'blue')
ax.annotate('Series 3', xy =(7.1, 10), color = 'green')
plt.show()

Here is the plot for the three rows of data in your sample dataframe: enter image description here

pakpe
  • 5,391
  • 2
  • 8
  • 23