The cross posting make it hard to answer, but I would rather the points here ...
Apart from not running on my machine (something about
convert_to_proportions that I don't care to debug or understand) the code you posted seems conceptually correct. Looking at an abridged version of the code
### Input the signal and noise values
## "sure signal", "likely signal", "guess signal", ... ... "sure noise"
signal = [1230, 496, 358, 272, 215, 165]
noise = [111, 216, 349, 540, 625, 895]
# cumulate them
csignal, cnoise = np.cumsum(signal), np.cumsum(noise)
# convert them to proportions and correct so that all but the last elements will never equal 1
propsignal = convert_to_proportions(csignal)
propnoise = convert_to_proportions(cnoise)
# calculate d' for all, except for the last element which is always 1.
d_primes = [get_d_prime(i, i) for i in zip(propsignal[0:-1], propnoise[0:-1])]
# calculate c in the same way
cs = [get_c(i, i) for i in zip(propsignal[0:-1], propnoise[0:-1])]
#estimate the noise and signal curves.
#*** This is where my numbers disagree with those in the paper.
estimated_noise = [stats.norm.cdf(-c) for c in cs]
estimated_signal = [stats.norm.cdf(np.mean(d_primes) - c) for c in cs]
you do not actually need to calculate
cs. I suggest instead just do
cs = np.arange(-10, 10, 0.01)
This way cs varies over the entire range of interest and makes a smooth curve and you avoid issues from interpolating between the points. When you do this, the fitted curve passes very close to the third data point, but in the manuscript the fitted curve passes very close to the fourth data point. The discrepancy between the paper and your plot seems to arise from
stats.norm.cdf(np.mean(d_primes) - c)
It turns out that
np.mean(d_primes) is very close to
d_primes (i.e., the $d^\prime$ associated with the third category). If we replace the offending line with
stats.norm.cdf(d_primes - c)
everything seems to line up.
From a conceptual standpoint, I think that
d_primes is the best estimate of $d^\prime$ since that corresponds to the division between possible signal and possible noise on the 6 point rating scale. That said, there may be a method for which
np.mean(d_primes) is the best choice. It is also worth noting that the numbers in the excel table in the paper do not match the figure in the paper.
In summary, if you want to get the numbers in the table, use
np.mean(d_primes), but if you want the figure to match use