Search code examples
pythonmatplotlibdata-visualizationdensity-plot

How to remove the rectagular white colored frame from my ax.pcolormesh() density plot?


from mplsoccer.pitch import Pitch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde

np.random.seed(19680801)
plt.style.use('dark_background')
fields = ['id', 'minute', 'result', 'X1', 'Y','xG','h_a','situation','season',
          'shotType','X']
df=pd.read_csv('shots.csv', skipinitialspace=True, usecols=fields)

df1 = pd.DataFrame({'A':df.Y,'B':df.X} )
a=(df1.to_numpy())
x, y = a.T
k = kde.gaussian_kde(a.T)

nbins=50

xi, yi = np.mgrid[x.min():x.max():nbins*1j, y.min():y.max():nbins*1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))

pitch = Pitch(orientation='vertical',pitch_type='metricasports', view='half',
              linewidth=2, line_zorder=1,
              line_color= '#94A7AE',pitch_length=105, pitch_width=68,pad_bottom=0)

fig, ax = pitch.draw()
ax.pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud', cmap='Reds',facecolor='black'
              )

ax.set_xlim(ax.get_xlim()[::-1])       
ax.yaxis.tick_right()  
plt.axis('off')
plt.show()

Output Plot here

I want the only red-colored density plot, not the white rectangular background frame. How to make the frame the same as my background?


Solution

  • Here is an approach using a colormap with an "under" color of 'none'. By setting vmin to a cut-off value, the cells with a lower value will get the "under" color ('none' stands for fully transparent). To get an idea of the values, temporarily a colorbar can be added. The values depend strongly on the extension of the x and y values (the integral of the kde is 1, so over a small domain the values need to be high enough).

    from mplsoccer.pitch import Pitch
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.stats import kde
    from copy import copy
    
    np.random.seed(19680801)
    plt.style.use('dark_background')
    # first create some random toy data roughly mimicking the given plot
    x = np.random.randn(100, 20).cumsum(axis=0).flatten()
    y = np.random.randn(100, 20).cumsum(axis=0).flatten()
    x = x * 0.04 + 0.5
    y = y * 0.01 + 0.9
    k = kde.gaussian_kde([x, y])
    
    nbins = 50
    xi, yi = np.mgrid[x.min():x.max():nbins * 1j, y.min():y.max():nbins * 1j]
    zi = k(np.vstack([xi.flatten(), yi.flatten()]))
    
    pitch = Pitch(orientation='vertical', pitch_type='metricasports', view='half',
                  linewidth=2, line_zorder=1,
                  line_color='#94A7AE', pitch_length=105, pitch_width=68, pad_bottom=0)
    
    fig, ax = pitch.draw()
    cmap = copy(plt.get_cmap('Reds'))
    cmap.set_under('none')
    pmesh = ax.pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud', cmap=cmap, vmin=5, facecolor='black')
    # fig.colorbar(pmesh, ax=ax) # to temporarily get an idea of the values
    ax.invert_xaxis()
    ax.yaxis.tick_right()
    plt.axis('off')
    plt.show()
    

    example plot