===Summary Horizontal Bar Chart=== This [[code:reports|code sample]] of a horizontal bar chart report. Horizontal bar charts are ideal when you want to show a //discrete// value (such as an **on/off** or **open/closed/transitioning** status) over time. In this case, we're showing a //summary// of how much time across the report range that the various assets were in different states. Asset names vary wildly in terms of length. Because of this, we suggest placing your asset names //inside// the report rather than placing them on one of your axes. {{hbar_summarised.png|400}} ==Customising== ^Element^Replace With^ |[PROPERTY]|The name of the property you want to report on| |[ASSETTYPE]|The title to show on the Y axis| ==The Code== import os import sys sys.path.insert(0,os.path.dirname(os.path.dirname(__file__))) import mplreport import discretepatterns as dp import pandas as pd import datetime @mplreport.ardireport("Sample Report") def CreateReport(report,args): #Create a page containing a single plot. fig,ax = report.CreatePage(1) #Print a title block for the page. report.Title() #Our AQL query goes here query = "('[PROPERTY]') PROPERTY ALLPOINTS" #Get the pandas data-frame with the results. Use the extended version that includes metadata. hist = report.FetchHistory(query) df = hist.data #Use the 'Discrete Patterns' class to convert discrete data into # time frames patterns = dp.DiscretePatterns() patterns.SetDataframe(df) patterns.Ready() #Establish a preferred order for the values order = [1,0] #Calculate total report time totaltime = (report.defaultend - report.defaultstart).total_seconds() #An array of asset names and summaries summaries = [] #Draw the bar chart indx = len(df.columns)-1 for col in df.columns: #Convert a discrete value into a set of time frames frames = patterns.GetAllTimeframes(col) #Get both colour and value maps map = report.GetDiscreteColourMap(hist,col) vmap = hist.GetValueMap(col) #We'll summarise the different values here... txt = "" #Go through the different values in the specified order realtotal = 0 for n in order: #Calculate the total time spent with this value total = 0 if n in frames: for frame in frames[n]: total += (frame[1] - frame[0]).total_seconds() #If there's anything to show... if total > 0: #Convert the total into a percentage... total = (total / totaltime) * 100 #Draw the total ax.broken_barh([(realtotal,total)],(indx,0.9),color=map[n]) realtotal += total #And update the line of text if txt != "": txt += " " txt += str(int(total*10)/10) + "% " + vmap[n] #Add the asset name to the line of text, and add it to the list. txt = col.replace(" [PROPERTY]","") + " - " + txt summaries.append(txt) indx-=1 #Draw in names indx = len(df.columns)-1 for col in summaries: ax.text(1, indx+0.18, col.strip(), c=(0,0,0,0.7)) indx -= 1 #Clear the Y axis ax.set_yticks(range(0,len(df.columns))) ax.set_yticklabels([""] * len(df.columns)) #Clean up and prettify ax.set_ylabel("[ASSETTYPE]") ax.set_xlabel("Time (%)") ax.margins(0,0) legend = report.GetDiscreteLegend(hist,df.columns[0]) ax.legend(handles=legend[0]) #Save this report out. report.Save()