Search code examples
pythonjsonmachine-learningstatisticsconfusion-matrix

Can I press on a cell in a confusion matrix and thereby open a file?


I want to make a confusion matrix that will allow me to press on any cell, and thus open a file of those prediction results. For example, when I press the cell in the ith row and jth column, it should open a json file that shows me all the items which were really type i but i predicted them to be type j.


Solution

  • You could try to use a mplcursor to perform an action when you click on a cell. An mplcursor has a parameter hover= which when set to False (the default) shows an annotation when you click. You could suppress the annotation and do another type of action. The mplcursor helps to identify where you clicked.

    Instead of hiding the annotation, you could fill it with the contents of the file. To close the annotation, either right click on it, or left click to open another.

    Here is some demo code with some invented dummy fields for the json file:

    from sklearn.metrics import confusion_matrix
    from matplotlib import pyplot as plt
    import mplcursors
    import json
    
    y_true = ["cat", "ant", "cat", "cat", "ant", "bird"]
    y_pred = ["ant", "ant", "cat", "cat", "ant", "cat"]
    labels = ["ant", "bird", "cat"]
    confusion_mat = confusion_matrix(y_true, y_pred, labels=labels)
    
    heatmap = plt.imshow(confusion_mat, cmap="plasma", interpolation='nearest')
    
    plt.colorbar(heatmap, ticks=range(3))
    
    plt.xticks(range(len(labels)), labels)
    plt.yticks(range(len(labels)), labels)
    
    cursor = mplcursors.cursor(heatmap, hover=False)
    @cursor.connect("add")
    def on_add(sel):
        i, j = sel.target.index
        filename = f'filename_{i}_{j}.json'
        text = f'Data about pred:{labels[i]} – actual:{labels[j]}\n'
        try:
            with open(filename) as json_file:
                data = json.load(json_file)
                for p in data['people']:
                    text += f"Name: {p['name']}\n"
                    text += f"Trials: {p['trials']}\n"
        except:
            text += f'file {filename} not found'
        sel.annotation.set_text(text)
    
    plt.show()