0

I have a code (see below) to plot a density scatter plot (2D histogram).

I would now like to add contour lines representing 7 selected percentiles (5%, 10%, 25%, 50%, 75%, 90%, 95%) of the number of data.

I have been googling solutions for too long now without finding any that really applies to my problem. So please, how can I do this?

import matplotlib.cm as cm
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# Create the fake data
a = np.random.randint(10, size=500)
b = np.random.randint(10, size=500)

# Sort B after A
p = a.argsort()              
A = a[p]     
B = b[p]   

# Set up xedges, yedges and colormap
xedges = np.arange(0.0, 10.0, 1)
yedges = np.arange(0.0, 10.0, 1)
cmap_DeScPl = cm.CMRmap_r
cmap_DeScPl.set_bad(color='white')
bounds_DeScPl =  np.arange(0, 31, 1)
norm_DeScPl = mpl.colors.BoundaryNorm(bounds_DeScPl, cmap_DeScPl.N)

# Plot the 2D Histogram
C, xedges, yedges = np.histogram2d(A, B, bins=(xedges, yedges))
CT = C.T
x, y = np.meshgrid(xedges, yedges)
plt.title('2D Histogram')
plt.pcolor(x, y, CT, cmap=cmap_DeScPl, norm=norm_DeScPl)
plt.subplots_adjust(bottom=0.1, right=0.8, top=0.9)
cax = plt.axes([0.82, 0.1, 0.075, 0.8])
plt.colorbar(cax=cax, label='Number of Data')
plt.show()

# Calculate Percentiles
CT_perc = np.zeros([7])
CT_perc[0] = np.percentile(CT, 5)
CT_perc[1] = np.percentile(CT, 10)
CT_perc[2] = np.percentile(CT, 25)
CT_perc[3] = np.percentile(CT, 50)
CT_perc[4] = np.percentile(CT, 75)
CT_perc[5] = np.percentile(CT, 90)
CT_perc[6] = np.percentile(CT, 95)

#Define a discrete colormap
nb_features = 7
contourlist = [np.array((0.,0.,0.)) for i in np.arange(nb_features)] 
contourlist[0] = np.array((40.,60.,230.))/255      # 5%      (blue)
contourlist[1] = np.array((50.,150.,200.))/255     # 10%     (light blue)
contourlist[2] = np.array((40.,220.,40.))/255      # 25%     (green)
contourlist[3] = np.array((220.,220.,50.))/255     # 50%     (yellow)
contourlist[4] = np.array((240.,30.,30.))/255      # 75%     (red)
contourlist[5] = np.array((180.,70.,30.))/255      # 90%     (brown)
contourlist[6] = np.array((40.,40.,40.))/255       # 95%     (black)
cmap_contour = mpl.colors.ListedColormap(contourlist)
colorbins = [0, CT_perc[0], CT_perc[1], CT_perc[2], CT_perc[3], CT_perc[4], CT_perc[5], CT_perc[6]]
norm_contour = mpl.colors.BoundaryNorm(colorbins, cmap_contour.N)

# Plot Contours of Percentiles
plt.title('Contour Lines of Percentiles')
plt.contour(x[:-1,:-1], y[:-1,:-1], CT, cmap=cmap_contour, norm=norm_contour)
plt.subplots_adjust(bottom=0.1, right=0.8, top=0.9)
cax = plt.axes([0.82, 0.1, 0.075, 0.8])
plt.colorbar(cax=cax, label='Number of Data')
plt.show()
honza_p
  • 2,073
  • 1
  • 23
  • 37
kirerik
  • 167
  • 1
  • 15
  • Not sure what the problem is. You can draw a contour plot with `plt.contour`. In how far does that no work? – ImportanceOfBeingErnest Jul 18 '18 at 10:31
  • @ImportenceOfBeingErnest You are right, but how can I specify which contour lines I want to draw? In my case I want to draw the contours of those 7 percentiles of number of data. – kirerik Jul 18 '18 at 11:43
  • I would really suggest you actually try to draw the contours and if that fails show the code you have a problem with. – ImportanceOfBeingErnest Jul 18 '18 at 11:45
  • @ImportanceOfBeingErnest I have now tried to add contour lines representing the percentiles. I have defined a discrete colormap and assigned its colors to the contour lines. Now it seems as if the lowest percentile contour lines are not plotted, but otherwise it is starting to plot what I want. Do you have any suggestions? Why are not all contour lines plotted and shown in the colorbar to the right? – kirerik Jul 18 '18 at 14:21
  • you need to specify the *levels* to use for your contour (the fouth argument). However, you will then run into the problem that percentiles for discrete data may not be unique, e.g. both the 10 and the 15 percentile may actually be the same number. What should happen in such case? – ImportanceOfBeingErnest Jul 18 '18 at 18:01

0 Answers0