0

I have data for a scatter plot (for reference, x values are labelled sm, y values are labelled bhm) and my three goals are to find the medians of binned data, create standard deviation bands, and create bands at the 90th and 10th percentiles. I've managed to do the first, and while I've been able to make vertical bars indicating the standard deviation, I can't figure out how to make filled-in bands since every time I try to set parameters with the fill_between function, it says operators with sm/bhm are incompatible since they're datasets and I'm comparing them to singular values (the mean line). I copied all of my code down below and there's a comment pointing out the relevant stuff - I just kept all of it since the variable names are a bit important and also because some parts of the plot don't show up properly without the seemingly extraneous code

To create the bands at 90/10 percent, I tried this bit of code by trying to bin the mean as I did for the median, and then filling the top and bottom of the line +-90% of the data but I keep getting

patsy.PatsyError: model is missing required outcome variables

#stuff that really doesn't work
model = smf.quantreg(bhm, sm)
quantiles = [0.1, 0.9]
fits = [model.fit(q=q) for q in quantiles]
figure, axes = plt.subplots()
_sm = np.linspace(min(sm), max(sm))

for index, quantile in enumerate(quantiles):
    _bhm = fits[index].params['world'] * _sm + 
    fits[index].params['Intercept']
    axes.plot(_sm, _bhm, label = quantile)

 axes.plot(_sm, _sm, 'g--', label = 'i guess this line is the mean')


#stuff that also doesn't really work 
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpatches
import h5py
import statistics as stat
import pandas as pd
import statsmodels.formula.api as smf

#my files and labels for things
f=h5py.File(r'C:\Users\hanna\Downloads\CatalogueGalsz0p0.hdf5', 'r')

sm = f['StellarMass']
bhm = f['BHMass']
bt = f['BtoT']
dt = f['DtoT']
nbins = 125

#titles and scaling for the plot
plt.title('Relationships Between Stellar Mass, Black Hole Mass, and Bulge 
to Total Ratios')
plt.xlabel('Stellar Mass')
plt.ylabel('Black Hole Mass')
plt.xscale('log')
plt.yscale('log')
axes = plt.gca()
axes.set_ylim([500000,max(bhm)])
axes.set_xlim([min(sm),max(sm)])

#labels for the legend and how I colored the points in the plot
DtoT = np.copy(f['DtoT'].value)
colour = np.zeros(len(DtoT),dtype=str)

for i in np.arange(0, len(bt)):
    if bt[i]>=0.5:
        colour[i]='green'
    else:
        colour[i]='red'


redbt = mpatches.Patch(color = 'red', label = 'Bulge to Total Ratios Below 0.5')
greenbt = mpatches.Patch(color = 'green', label = 'Bulge to Total Ratios Above 0.5')
plt.legend(handles = [(redbt), (greenbt)])

#the important part - this is how I binned my data to make the median line, and this part works but not the standard deviation bands 
bins = np.linspace(0, max(sm), nbins)
delta = bins[1]-bins[0]
idx = np.digitize(sm, bins)
runningmedian = [np.median(bhm[idx==k]) for k in range(nbins)]
runningstd = [bhm[idx==k].std() for k in range(nbins)]


plt.plot(bins-delta/2, runningmedian, c = 'b', lw=1)
plt.scatter(sm, bhm, c=colour, s=.2)

plt.show()
BenT
  • 3,172
  • 3
  • 18
  • 38
Starsyph
  • 13
  • 5
  • How about this https://stackoverflow.com/questions/23248435/fill-between-two-vertical-lines-in-matplotlib – Ardweaden Jul 25 '19 at 13:26
  • Thanks, but that's for vertical lines whereas I'm trying to make filled-in error bars. I've read through a bunch of similar solutions here but none of them have worked for me thus far and I'm not sure why - I also started using numpy three days ago so I could just be making an extremely basic error; at this point, I'm not sure – Starsyph Jul 25 '19 at 13:44
  • 1
    Start with a [mcve]. First, it would ease it to see basic errors yourself; also it would allow others to help. – ImportanceOfBeingErnest Jul 25 '19 at 13:54
  • The comment above is very true. However, `fill_between` accepts 3 numpy arrays. You can convert pandas dataframes to numpy arrays with `.to_numpy()`. – Ardweaden Jul 25 '19 at 15:13

0 Answers0