CamDavidsonPilon / lifelines

Survival analysis in Python
lifelines.readthedocs.org
MIT License
2.37k stars 560 forks source link

Cumulative plot with show_censors option #940

Closed tsjshg closed 4 years ago

tsjshg commented 4 years ago

When I use KaplanMeierFitter.plot_cumulative_density with show_censors=True, I got AttributeError: 'PlotEstimateConfig' object has no attribute 'predict_at_times'.

I modified the end of plotting.py from

        else:
            self.estimate_ = estimate
            self.confidence_interval_ = kwargs.pop("confidence_intervals")

to

        else:
            self.estimate_ = estimate
            self.confidence_interval_ = kwargs.pop("confidence_intervals")
            self.predict_at_times = cls.cumulative_density_at_times

I successfully got my cumulative plot. But I think the code should be changed more correct way.

CamDavidsonPilon commented 4 years ago

Hi there, I'm not able to reproduce your error. Can you check what version of lifelines you are on?

import lifelines; print(lifelines.__version__)
tsjshg commented 4 years ago

Hi Cameron, In version 0.23.2, I got an error as I run the following code with jupyter notebook.

import lifelines
import lifelines.datasets
%matplotlib inline
data = lifelines.datasets.load_canadian_senators()
KaplanMeierFitter = lifelines.KaplanMeierFitter
kmf = KaplanMeierFitter()
kmf.fit(data['diff_days'], data['observed'])
kmf.plot_cumulative_density(show_censors=True)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-36190c174977> in <module>
      2 kmf = KaplanMeierFitter()
      3 kmf.fit(data['diff_days'], data['observed'])
----> 4 kmf.plot_cumulative_density(show_censors=True)
      5 #kmf.plot()

~/anaconda3/lib/python3.7/site-packages/lifelines/fitters/kaplan_meier_fitter.py in plot_cumulative_density(self, **kwargs)
    368             estimate=self.cumulative_density_,
    369             confidence_intervals=self.confidence_interval_cumulative_density_,
--> 370             **kwargs
    371         )
    372 

~/anaconda3/lib/python3.7/site-packages/lifelines/plotting.py in _plot_estimate(cls, estimate, loc, iloc, show_censors, censor_styles, ci_legend, ci_force_lines, ci_alpha, ci_show, at_risk_counts, ax, **kwargs)
    601             float
    602         )
--> 603         v = plot_estimate_config.predict_at_times(censored_times).values
    604         plot_estimate_config.ax.plot(censored_times, v, linestyle="None", color=plot_estimate_config.colour, **cs)
    605 

AttributeError: 'PlotEstimateConfig' object has no attribute 'predict_at_times'

By the way, in version 0.21.2, I got a figure like this.

plot

CamDavidsonPilon commented 4 years ago

Thanks! I can now reproduce the error. This helps a lot. I'll fix for a future release.

To your second issue: yes, that was fixed in 0.22.1

CamDavidsonPilon commented 4 years ago

@tsjshg a better solution, and the one I'll implement, is to change the following:

from lifelines.plotting import _plot_estimate  

def plot_cumulative_density(self, **kwargs):
    return _plot_estimate(
        self,
        estimate="cumulative_density_",
        **kwargs
    )

KaplanMeierFitter.plot_cumulative_density = plot_cumulative_density

So your entire script becomes:

import lifelines
from lifelines.datasets import load_canadian_senators
data = load_canadian_senators()

from lifelines.plotting import _plot_estimate  

def plot_cumulative_density(self, **kwargs):
    return _plot_estimate(
        self,
        estimate="cumulative_density_",
        **kwargs
    )

KaplanMeierFitter.plot_cumulative_density = plot_cumulative_density

kmf = KaplanMeierFitter()
kmf.fit(data['diff_days'], data['observed'])
kmf.plot_cumulative_density(show_censors=True)
tsjshg commented 4 years ago

Hi Cameron, your solution fixed the error in version 0.23.9. I really appreciate your prompt response, and giving us this great library for lifetime data analysis!