Path Tracing and Heatmap - NorrisLab/DLC_Python_Scripts GitHub Wiki

How to create a Path Tracing and Heatmap from a DLC h5 file

Code in reference: link to code

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: