0

I wanted to create a visualisation like this below - enter image description here

I have succeeded in implementing the code from this answer to get this image below enter image description here

As can be seen from comparing both images, the difference in colours is great even though the mappable is the same series. Do I need to create my own colourmap for the colours to be more pronounced? My second issue is how do I plot a colorbar for the entire figure?

My code looks like this:


fig, ax = plt.subplots()


##Sonars plotting function - 
def plot_inset(width, axis_main, data, x,y):
    ax_sub= inset_axes(axis_main, width=width, height=width, loc=10, 
                       bbox_to_anchor=(x,y),
                       bbox_transform=axis_main.transData, 
                       borderpad=0.0, axes_class=get_projection_class("polar"))

    theta = data["Bin_Mids"]
    radii = data["Frequency"]
    length = data["pass.length"]
    colors = plt.cm.magma(length/100)
    bars = ax_sub.bar(theta, radii, width=0.3, bottom=0.0, color = colors, alpha=0.5)
    ax_sub.set_xticklabels([])
    ax_sub.set_yticks([])
    ax_sub.yaxis.grid(False)
    ax_sub.xaxis.grid(False)
    ax_sub.spines['polar'].set_visible(False)

##Calling the function
for player, loc in player_dict.items():
    plot_inset(1.1,ax, data = Passer(player), x = loc[0], y = loc[1])
    ax.text(loc[0]+10, loc[1], player, size = 6.25, rotation = -90)

player_dict looks like this (sample):

player_dict = {'Sarah Bouhaddi': [0, 45], 'Marion Torrent': [42, 15], 'Gaëtane Thiney': [97, 68]} ##the list for every player is their x,y co-ordinate

The data I'm sending to the plotting function for every player is a dataframe and looks like this (a sample) -

   Bin_Mids  pass.length  Frequency
0    1.3660    27.202942          1
1    1.0925    23.024565          3
2    0.8195    16.834414          3
3    0.5465    14.008925          1
4   -0.2735    21.906391          1
5   -0.5465    19.285486          1
6   -0.8195    20.975364          4
7   -1.0925    23.735166          3

Secondary Issue

Another problem I'm facing is to prevent the polar sonars from hiding the pitch lines. I tried setting a zorder but that didn't work. Is there a way to make the frame of the sonars invisible?

Any help would be appreciated. I'm not sure if the issues in this question all deserve questions of their own so I clubbed them all together as they're related.

Abhishek
  • 553
  • 2
  • 9
  • 26
  • Colormaps map a value between 0 and 1 to a color. All your values seem to be in the range [0.1, 0.3] so they look pretty similar. Use the full range [0,1] to have them fill the complete spectrum of the colormap. – ImportanceOfBeingErnest Jun 24 '19 at 09:20
  • Thank you for your comment. However, I'd have to create false data for that. Is there no way to say, create a custom colourmap who's range is equal to my range - [0.1,0.3] so I can get more perceptive results? Also, could you help me out with the other problems i.e. how to plot the colorbar of the same and how to prevent the polar plots from overlapping each other as well as the other lines on the figure? – Abhishek Jun 24 '19 at 11:54
  • By definition a colormap in matplotlib maps values between 0 and 1 to colors. So every matplotlib plot you see in the wild uses what you call "false data". Usually one would just normalize the data between the minimum and maximum value. – ImportanceOfBeingErnest Jun 24 '19 at 12:07
  • How would I go about trying to normalize my data for the colourmap then? Or how do I use the full range? – Abhishek Jun 24 '19 at 12:14
  • If `a` is a numpy array of data, then `norm=plt.Normalize(a.min(), a.max())` would be a useful normalization. If `cmap` is a matplotlib colormap, then `cmap(norm(a))` would give the colors spread over the complete colormap range. – ImportanceOfBeingErnest Jun 24 '19 at 12:22
  • Great thanks! And since most of the axes inset function is yours, could you suggest a way to prevent overlaps and keep only the bars or would that constitute a separate question? – Abhishek Jun 24 '19 at 13:01
  • The code in your question does not show anything that would overlap – ImportanceOfBeingErnest Jun 24 '19 at 13:19
  • They're a lot of lines that I didn't include to keep the example minimal in nature. There are bunch of plt.plot([],[]). – Abhishek Jun 24 '19 at 15:12
  • Furthermore, I did create a colormap out of the array but I am unable to plot it separately for the individual plots as I don't know how to pass a colormap argument. If I should use a for loop to set facecolor for the individual bars, how do I get the corresponding colormap value from the main colormap of the entire plot? – Abhishek Jun 24 '19 at 17:52
  • In your case you will need to pass the normalization as argument to your function, such that you can use the same normalization in all individual plots. – ImportanceOfBeingErnest Jun 24 '19 at 19:15
  • That worked, thank you. How do I plot a colorbar for the entire figure? I tried plt.colorbar() but that didn't work as there's no mappable. I'm not sure what the mappable should be. – Abhishek Jun 25 '19 at 16:51
  • 1
    You need to create it yourself `ScalarMappable(cmap=cmap, norm=norm)` – ImportanceOfBeingErnest Jun 25 '19 at 16:59

0 Answers0