I am working on a QC tool to "flag" questionable data from time series based on multiple criteria. Good data would be flagged to 1, bad data to 0. I would like to display the resulting array containing 0 and 1 values as color-coded horizontal bar.
Let's consider the following dummy array myarray
:
import numpy as np
import matplotlib.pyplot as plt
mysamples=np.arange(3600)
myarray = np.ones(3600)
myarray[300:500]=0
myarray[1300:1800]=0
I came up with the following solutions to display it:
Solution using bar
fig, axs = plt.subplots(2, gridspec_kw={'height_ratios': [5, 1]})
fig.suptitle('QC flag example 1')
axs[0].plot(mysamples,myarray)
axs[1].bar(mysamples[myarray==1], height=1, linewidth=0, color='green')
axs[1].bar(mysamples[myarray==0], height=1, linewidth=0, color='red')
Solution using scatter
fig, axs = plt.subplots(2, gridspec_kw={'height_ratios': [5, 1]})
fig.suptitle('QC flag example 2')
axs[0].plot(mysamples,myarray)
axs[1].scatter(mysamples[myarray==1],mysamples[myarray==1]*0 , marker='s', color='green')
axs[1].scatter(mysamples[myarray==0], mysamples[myarray==0]*0, marker='s', color='red')
I prefer option 2 as it would allow me to plot multiple QC tracks on top of each other, but I still think that it is a convoluted way to display myarray
. For instance, if the marker size is not handled properly, it may end up producing a discontinuous bar chart.
Is there any other matplotlib function that would allow to create such a horizontal bar?
Note: I know that plotly
has heaps of options such as Gantt charts, but for the time being, I would prefer to stick to matplotlib.
CodePudding user response:
I'm not sure how much simpler this is, but I used horizontal bar charts to deal with it. Create an array1 of the same length and use the original array for color determination. It is then stacked in a loop process with the index as the left position.
fig, axs = plt.subplots(2, gridspec_kw={'height_ratios': [5, 1]})
fig.suptitle('QC flag example 1')
axs[0].plot(mysamples,myarray)
# axs[1].bar(mysamples[myarray==1], height=1, linewidth=0, color='green')
# axs[1].bar(mysamples[myarray==0], height=1, linewidth=0, color='red')
new_array = [1]*len(myarray)
colors = [('g' if i == 1 else 'r') for i in myarray]
for i,a in enumerate(new_array):
axs[1].barh(y=0, width=a, height=0.5, left=i, color=colors[i])
x0,x1 = axs[0].get_xlim()
axs[1].set_xlim(x0, x1)
plt.show()