title: How to plot a cumulative distribution function weighted by the values (eg how many people live in cities >1m)
body: <p>I have a dataset with few, very large observations, and <strong>I am interested in the histogram and the cumulative distribution function weighted by the values themselves.</strong></p>
  
  <p>Think of it like having a table that shows the inhabitants for each city in a region/country. <em>I don't care how many towns there are, I only care that, say, 20% of the population lives in towns with fewer than 10,000 people</em>, 10% of the population lives in large cities of more than 1 million people, etc.</p>
  
  <p>Matplotlib and seaborn can calculate weighted histograms - see code below.</p>
  
  <p><strong>My issue is with the CDF</strong>:</p>
  
  <ul>
  <li>numpy.histogram with density=True returns the value of the probability density function at the bins, <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html" rel="nofollow noreferrer">so the values do not necessarily sum to 1</a></li>
  <li>matplotlib.pyplot.hist with density = True returns values that do sum to 1, but it also plots the histogram, whereas I just want the values to then plot a line myself (line, not histogram)</li>
  <li>statsmodels.distributions.empirical_distribution.ECDF cannot accept weights</li>
  </ul>
  
  <p><strong>What I have come up with is using numpy.histogram and then rescaling myself:</strong></p>
  
  <pre><code>hist_nodens, bin_edges_nodens=np.histogram(d, 100, weights=d, density=False)
  hist_nodens /= np.sum(hist_nodens)
  sns.lineplot(bin_edges_nodens[1:], np.cumsum(hist_nodens))
  </code></pre>
  
  <p><strong>It works, but I was wondering if there are other ways?</strong> Using matplotlib.pyplot.hist to create a plot then close it seems more cumbersome. </p>
  
  <p>I have put together a toy example here. The y axis goes to 1 in chart D but not in C</p>
  
  <pre><code>import numpy as np
  from statsmodels.distributions.empirical_distribution import ECDF
  import matplotlib.pyplot as plt
  import seaborn as sns
  
  d= np.hstack([\
                np.random.randint(100,1000,4000),
                np.arange(10000,100000,100), \
                np.linspace(200e3,900e3,20), \
                1e6,2e6,4e6
                ])
  
  s=np.sum(d) / 1e6
  
  d /= 1e3
  
  fig,ax=plt.subplots(1,5)
  
  ax[0].set_title('A) Histogram - weighted')
  sns.distplot( d, 100,  kde=False, norm_hist=True, ax=ax[0], hist_kws={'weights':d} )
  
  ax[1].set_title('B) Cumulative weighted histogram')
  sns.distplot( d, 100, kde=False, norm_hist=True, ax=ax[1], hist_kws={'weights':d,'cumulative':True} )
  
  ax[2].set_title('C) Weighted ECDF \n from np.histogram dens=True')
  hist, bin_edges=np.histogram(d, 100, weights=d, density=True)
  hist=np.cumsum(hist)
  sns.lineplot(bin_edges[1:], hist, ax=ax[2])
  
  ax[3].set_title('D) Weighted ECDF \n from np.histogram dens=False')
  hist_nodens, bin_edges_nodens=np.histogram(d, 100, weights=d, density=False)
  hist_nodens /= np.sum(hist_nodens)
  sns.lineplot(bin_edges_nodens[1:], np.cumsum(hist_nodens), ax=ax[3])
  
  py_n,py_bins,py_patches=plt.hist( d,100, weights=d, density=True, cumulative=True)
  
  ax[4].set_title('E) ECDF - not weighted')
  ecdf=ECDF( d  )
  x=np.linspace( min(d), max(d), num=1000 )
  y=ecdf(x)
  ax[4].step(x,y)
  </code></pre>