====Heatmap Reports==== When [[creating_a_traditional_report|creating a report]], we found that there were simply too many channels of data to display everything on a single line chart. One way of resolving this is by [[a_multi-page_report_with_individual_graphs|splitting our individual channels up into their own charts]]. This is ideal if you're looking for issues along individual assets. But if you're looking for patterns or inconsistencies //across// your assets, a heatmap is often a better option. ===Picking a Resolution=== Normally, heatmaps are at a slightly lower time-resolution compared to line graphs. We find that 500-1000 time-samples across your X axis is very readable for users. To do this, you can set the **samples** parameter in the call to **GetHistory**. df = report.GetHistory(query,samples=500) ===Choosing a Colour Scale=== One question that comes up with heatmaps is what //colour scale// to use for the data. One of the best scales to use is known as **viridis**, specifically designed to give a good impression of a value, even for people with common colour-vision issues (such as red-green colour-blindness). But some ARDI analogue points include their own distinct colour-map, used to highlight issues at specific value thresholds (ie. green in good ranges, blue when low and red when high). If we call **FetchHistory** instead of **GetHistory**, we also have access to the ARDI metadata as well as the pandas DataFrame. With the metadata available, we can use the **GetAnalogColourMap** function to return an array made up of... ^Element^Content^ |0|A MatPlotLib colour map| |1|The minimum value of the range| |2|The maximum value of the range| #Get the pandas data-frame with the results. hist = report.FetchHistory(query,samples=500) df = hist.data #Get a colour map, minimum and maximum value from the column information map = report.GetAnalogColourMap(hist,df.columns[0]) ===Building the Heatmap=== #Draw the heatmap itself im = ax.imshow(df.T,cmap=map[0],interpolation='nearest',aspect='auto',vmin=map[1],vmax=map[2]) #Clean up and prettify ax.set_ylabel("Turbine") ax.set_xlabel("Time") ax.margins(0,0) report.HeatMapTimeAxis(ax.xaxis,500) This takes advantage of the **HeatMapTimeAxis** function, which is used to convert a sequence of numbers something that //looks// like a time axis. ===Adding a Colour Legend=== The following code creates a //colour bar// on the right-hand side of your report, describing the values that your different colours represent. #Draw a reference scale cbar = ax.figure.colorbar(im, ax=ax) cbar.ax.set_ylabel("Vibration (mm/s/s)", rotation=-90, va="bottom") ===The Y Axis=== One issue with the default appearance of a heatmap report is the labels on the Y axis. Showing the names of the assets //outside// the axes squashes your heatmap quite a lot. The code below places the axis labels on the **inside** of the axes instead. #Draw in names indx = len(df.columns)-1 for col in df.columns: ax.text(2,indx+0.18,col.replace(" Vibration","").strip(), c=(0.5,0.5,0.5,0.6)) indx -= 1 #Clear the X axis ax.set_yticks(range(0,len(df.columns))) ax.set_yticklabels([""] * len(df.columns)) ===Results=== This gives us a heatmap of the vibration across each of our wind turbines. {{heatmapping.png}} You can find more report examples [[code:reports|here]]. Now that we've build a report, why not try an [[non-traditional reports|less traditional style of report]]?