Search code examples
pythonmatplotlibfontslegenditalics

Font and colour for Python matplotlib legend- superscript


Can someone help me make the R2 writing look like the rest? Especially not italics. This is my code below:

While I'm here can anyone tell me how to either

  • get that R2=0.97 line in red writing to indicate that's what the red line is on the graph or
  • insert a red line/red dash within the legend on that line?

I've seen other ways of doing it online but the way I've formatted my legend doesn't allow for it.

plt.rcParams["font.family"] = "Cambria"
fig, ax = plt.subplots()
ax.scatter(y_test, y_predicted ,s=10,color='darkslateblue',linewidths=1)
ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k-', lw=2,)
ax.set_xlabel('Actual (%)',fontsize='large')
ax.set_ylabel('Predicted (%)',fontsize='large')
y_test, y_predicted = y_test.reshape(-1,1), y_predicted.reshape(-1,1)
ax.plot(y_test, LinearRegression().fit(y_test, y_predicted).predict(y_test), color="red", lw=2)
ax.set_title('H2O REF')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
                                 lw=0, alpha=0)] * 4
labels = []
labels.append("$R^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
ax.legend(handles, labels, loc='best', fontsize='x-large',
          fancybox=True, framealpha=0.7,
          handlelength=0, handletextpad=0)
plt.show()

enter image description here

Thank you :)


Solution

  • For the first solution, a possible way to achieve it is by only typesetting ^2 in the math environment and than setting the first label text to red as described here, see code below.

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.patches as mpl_patches
    
    x = np.linspace(0, 1)
    y = x + np.random.normal(scale=0.1, size=50)
    
    plt.rcParams["font.family"] = "Cambria"
    Rsquared = 0.9
    rmse = 0.8
    mae = 1
    
    fig, ax = plt.subplots()
    ax.scatter(x, y)
    ax.plot(x, x, c='r')
    
    handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
                                     lw=0, alpha=0)] * 4
    
    labels = []
    labels.append("R$^2$ = {0:.2g}".format(Rsquared))
    labels.append("RMSE = {0:.2g}".format(rmse))
    labels.append("MAE = {0:.2g}".format(mae))
    leg = ax.legend(handles, labels, loc='best', fontsize='x-large',
              fancybox=True, framealpha=0.7,
              handlelength=0, handletextpad=0)
    
    texts = leg.get_texts()
    texts[0].set_color("red")
    

    Alternatively, you can create legend entries including the red line with Line2D. The corresponding code down below overrides handles[0].

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.patches as mpl_patches
    from matplotlib.lines import Line2D
    
    x = np.linspace(0, 1)
    y = x + np.random.normal(scale=0.1, size=50)
    
    
    plt.rcParams["font.family"] = "Cambria"
    Rsquared = 0.9
    rmse = 0.8
    mae = 1
    
    fig, ax = plt.subplots()
    ax.scatter(x, y)
    ax.plot(x, x, c='r')
    
    handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
                                     lw=0, alpha=0)] * 4
    
    lines = []
    handles[0] = Line2D([0], [0], color='red')
    labels = []
    labels.append("R$^2$ = {0:.2g}".format(Rsquared))
    labels.append("RMSE = {0:.2g}".format(rmse))
    labels.append("MAE = {0:.2g}".format(mae))
    leg = ax.legend(handles, labels, loc='best', fontsize='x-large',
              fancybox=True, framealpha=0.7)