Path Tracing and Heatmap - NorrisLab/DLC_Python_Scripts GitHub Wiki
How to create a Path Tracing and Heatmap from a DLC h5 file
link to code
Code in reference:
You will need to understand the naming conventions of these generated files. For example:
Vglut-cre C135 M3+_2_DLC_resnet50_EnclosedBehaviorMay27shuffle1_307000_filtered.h5
|------Video Name-----|-------------DLCscorer--------------------------|
Basic Imports:
import pandas as pd
from pathlib import Path
import os
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
Change the fps
to reflect what videos were recorded in. Change the DLCscorer
to reflect what is in the generated file.
Formatting graph function:
Parameters
----------
graph_title : STRING
Ideally this should be a string with the animal name. This function will format the graph to Arial 12 font with thin
lines that is consistent with our general figure formatting
Returns
-------
None.
This function will save the generated plot in a 600dpi image. By default the images are saved as jpgs but this can be
changed to a variety of different formats.
Note: You can change the ".jpg" to whatever image format you would desire (ex: png, eps, etc). You can change the dpi
value to increase clarity of image.
def format_graph(graph_title):
font = {'family': 'Arial',
'size': 12}
plt.rc('font', **font)
plt.rc('lines', linewidth = 1)
plt.gca().spines['right'].set_color('none')
plt.gca().spines['top'].set_color('none')
plt.title(graph_title, fontsize=12)
plt.savefig(graph_title+".jpg", dpi=600)
plt.show()
Heatmap and Path plotting function
Example of calling function: heatmap(video='TopDown_TestMouse_Top Down', body_part='head', color='#7ca338', plot_title='TopDown Test Animal')
Parameters
----------
video : STRING
The inital part of the video PRIOR to the DLC_resnet part, this serves as a unique identifier when multiple videos are
used from the same scorer.
body_part : STRING
A string that references the body part that you would like to annotate. This **MUST** be one of the body parts that was
analyzed using DLC. Ex: head, tailbase, etc. Be cognizant of how this was typed in the config.yaml file.
color : STRING
A string that references a color. This can be fully written out in a word or the Hex code can be provided.
plot_title : STRING
Title prefix for the plots that will be generated. For the Tracing plots it will be the name of the plot followed by the
words "Path Tracing". In the case of the heatmap this will name of the plots will be followed by "Heatmap".
Returns
-------
None.
2 plots will be generated. One for the heatmap and the other for the path tracing.
def heatmap(video, body_part, color, plot_title):
dataname = str(Path(video).stem) + DLCscorer + 'filtered.h5'
# print(dataname) ##this can be uncommented to print the full dataname to get an idea of what's going on
Dataframe = pd.read_hdf(os.path.join(dataname), errors='ignore')
bpt = body_part
x_y_cord_df = pd.DataFrame()
x_y_cord_df['x'] = Dataframe[DLCscorer][bpt]['x'].values
x_y_cord_df['y'] = Dataframe[DLCscorer][bpt]['y'].values
# print(x_y_cord_df)
plt.plot(x_y_cord_df['x'], x_y_cord_df['y'], color=color)
format_graph(plot_title+" Path Tracing")
plt.show()
plt.hist2d(x_y_cord_df['x'], x_y_cord_df['y'], bins=35)
cb1=plt.colorbar(orientation="vertical")
cb1.set_ticks([])
# plt.clim(0, fps) #limit for colorbar
# sfmt=ticker.ScalarFormatter(useMathText=True) #makes the label look more "math like"
# cb1=plt.colorbar(orientation="vertical",format=sfmt) #vertical orientation with scientific number formatting
# cb1.set_label(r'$number of frames$')
format_graph(plot_title+" Heatmap")
plt.show()
dataname = str(Path(video).stem) + DLCscorer + 'filtered.h5'
this will generate the whole stem of the video based on the video
and DLCscorer
that was specified.
Dataframe = pd.read_hdf(os.path.join(dataname), errors='ignore')
will loading output of DLC by reading the H5 file and storing it into DataFrame
. You could also replace read_hdf
with read_csv
to read from a CSV file instead. I mainly worked with H5 files since they were smaller and less cumbersome to deal with.
This part of code plots the path tracing based on the x and y coordinate values found in the DataFrame
:
bpt = body_part
x_y_cord_df = pd.DataFrame()
x_y_cord_df['x'] = Dataframe[DLCscorer][bpt]['x'].values
x_y_cord_df['y'] = Dataframe[DLCscorer][bpt]['y'].values
# print(x_y_cord_df)
plt.plot(x_y_cord_df['x'], x_y_cord_df['y'], color=color)
format_graph(plot_title+" Path Tracing")
plt.show()
plt.hist2d(x_y_cord_df['x'], x_y_cord_df['y'], bins=35)
this part of the code plots a heatmap based on where the body_part
was located during analysis. You shouldn't need to change anything else in this code except for the bin
number. Refer to the simple heatmap code for more detail on what changing the bin
number does.
These two lines will plot a vertical colorbar that is empty, which is the default:
cb1=plt.colorbar(orientation="vertical")
cb1.set_ticks([])
If you want to plot a more detailed looking colorbar, uncomment this portion of the code:
plt.clim(0, fps) #limit for colorbar
sfmt=ticker.ScalarFormatter(useMathText=True) #makes the label look more "math like"
cb1=plt.colorbar(orientation="vertical",format=sfmt) #vertical orientation with scientific number formatting
cb1.set_label(r'$number of frames$')
You'll end up generating a colorbar which looks like the image to the right: