Search code examples
pythonmatplotlibdata-sciencevisualizationviolin-plot

Annotate Min/Max/Median in Matplotlib Violin Plot


Given this example code:

import pandas as pd
import matplotlib.pyplot as plt


data = 'https://raw.githubusercontent.com/marsja/jupyter/master/flanks.csv'

df = pd.read_csv(data, index_col=0)

# Subsetting using Pandas query():
congruent = df.query('TrialType == "congruent"')['RT']
incongruent = df.query('TrialType == "incongruent"')['RT']

# Combine data
plot_data = list([incongruent, congruent])

fig, ax = plt.subplots()

xticklabels = ['Incongruent', 'Congruent']
ax.set_xticks([1, 2])
ax.set_xticklabels(xticklabels)

ax.violinplot(plot_data, showmedians=True)

Which results in the following plot:

enter image description here

How can I annotate the min, max, and mean lines with their respective values?

I haven't been able to find examples online that allude to how to annotate violin plots in this way. If we set plot = ax.violinplot(plot_data, showmedians=True) then we can access attributes like plot['cmaxes'] but I cant quite figure out how to use that for annotations.

Here is an example of what I am trying to achieve:

enter image description here


Solution

  • So this was as easy as getting the medians/mins/maxes and then enumerating, adding the annotation with plt.text, and adding some small values for positioning:

    medians = results_df.groupby(['model_cat'])['test_f1'].median()
    
    for i, v in enumerate(medians):
        plt.text((i+.85), (v+.001), str(round(v, 3)), fontsize = 12)