hammerlab / cohorts

Utilities for analyzing mutations and neoepitopes in patient cohorts
Apache License 2.0
20 stars 4 forks source link

Invalid RGBA argument error using `plot_survival` #221

Closed jburos closed 7 years ago

jburos commented 7 years ago

I'm using plot_survival on a cohort & am getting a strange error:

Input:

my_cohort.plot_survival(on='age')

Output:

ValueError: Invalid RGBA argument: 0.6627450980392157

Using Python 3.5.2 & matplotlib 2.0.2 (installed via conda)

Python 3.5.2 :: Continuum Analytics, Inc.
matplotlib                2.0.2               np113py35_0

Here is the traceback:

# no condition 29
# with condition 27
Out[14]:
<lifelines.StatisticalResult: 
Results
   null distribution: chi squared
   alpha: 0.95
   df: 1
   test: logrank
   t 0: -1

   __ p-value ___|__ test statistic __|____ test result ____|__ is significant __
         0.69421 |              0.155 |  Cannot Reject Null |       False       
>
/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/font_manager.py:1297: UserWarning: findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
    140     try:
--> 141         rgba = _colors_full_map.cache[c, alpha]
    142     except (KeyError, TypeError):  # Not in cache, or unhashable.

KeyError: (0.6627450980392157, None)

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/IPython/core/formatters.py in __call__(self, obj)
    305                 pass
    306             else:
--> 307                 return printer(obj)
    308             # Finally look for special method names
    309             method = get_real_method(obj, self.print_method)

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/IPython/core/pylabtools.py in <lambda>(fig)
    225 
    226     if 'png' in formats:
--> 227         png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
    228     if 'retina' in formats or 'png2x' in formats:
    229         png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/IPython/core/pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
    117 
    118     bytes_io = BytesIO()
--> 119     fig.canvas.print_figure(bytes_io, **kw)
    120     data = bytes_io.getvalue()
    121     if fmt == 'svg':

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
   2198                     orientation=orientation,
   2199                     dryrun=True,
-> 2200                     **kwargs)
   2201                 renderer = self.figure._cachedRenderer
   2202                 bbox_inches = self.figure.get_tightbbox(renderer)

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, *args, **kwargs)
    543 
    544     def print_png(self, filename_or_obj, *args, **kwargs):
--> 545         FigureCanvasAgg.draw(self)
    546         renderer = self.get_renderer()
    547         original_dpi = renderer.dpi

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py in draw(self)
    462 
    463         try:
--> 464             self.figure.draw(self.renderer)
    465         finally:
    466             RendererAgg.lock.release()

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     61     def draw_wrapper(artist, renderer, *args, **kwargs):
     62         before(artist, renderer)
---> 63         draw(artist, renderer, *args, **kwargs)
     64         after(artist, renderer)
     65 

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/figure.py in draw(self, renderer)
   1142 
   1143             mimage._draw_list_compositing_images(
-> 1144                 renderer, self, dsu, self.suppressComposite)
   1145 
   1146             renderer.close_group('figure')

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, dsu, suppress_composite)
    137     if not_composite or not has_images:
    138         for zorder, a in dsu:
--> 139             a.draw(renderer)
    140     else:
    141         # Composite any adjacent images together

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     61     def draw_wrapper(artist, renderer, *args, **kwargs):
     62         before(artist, renderer)
---> 63         draw(artist, renderer, *args, **kwargs)
     64         after(artist, renderer)
     65 

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
   2424             renderer.stop_rasterizing()
   2425 
-> 2426         mimage._draw_list_compositing_images(renderer, self, dsu)
   2427 
   2428         renderer.close_group('axes')

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, dsu, suppress_composite)
    137     if not_composite or not has_images:
    138         for zorder, a in dsu:
--> 139             a.draw(renderer)
    140     else:
    141         # Composite any adjacent images together

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     61     def draw_wrapper(artist, renderer, *args, **kwargs):
     62         before(artist, renderer)
---> 63         draw(artist, renderer, *args, **kwargs)
     64         after(artist, renderer)
     65 

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/lines.py in draw(self, renderer)
    801                 self._set_gc_clip(gc)
    802 
--> 803                 ln_color_rgba = self._get_rgba_ln_color()
    804                 gc.set_foreground(ln_color_rgba, isRGBA=True)
    805                 gc.set_alpha(ln_color_rgba[3])

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/lines.py in _get_rgba_ln_color(self, alt)
   1342 
   1343     def _get_rgba_ln_color(self, alt=False):
-> 1344         return mcolors.to_rgba(self._color, self._alpha)
   1345 
   1346     # some aliases....

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
    141         rgba = _colors_full_map.cache[c, alpha]
    142     except (KeyError, TypeError):  # Not in cache, or unhashable.
--> 143         rgba = _to_rgba_no_colorcycle(c, alpha)
    144         try:
    145             _colors_full_map.cache[c, alpha] = rgba

/home/jacquelineburos/miniconda3/envs/rcc/lib/python3.5/site-packages/matplotlib/colors.py in _to_rgba_no_colorcycle(c, alpha)
    192         # float)` and `np.array(...).astype(float)` all convert "0.5" to 0.5.
    193         # Test dimensionality to reject single floats.
--> 194         raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
    195     # Return a tuple to prevent the cached value from being modified.
    196     c = tuple(c.astype(float))

ValueError: Invalid RGBA argument: 0.6627450980392157

<matplotlib.figure.Figure at 0x7f55c8139ba8>
jburos commented 7 years ago

When this problem surfaced, the lifelines version was 0.9.3.2. It was resolved by removing these two lines in survival.py:

with_condition_color = colors.hex2color(with_condition_color)
no_condition_color = colors.hex2color(no_condition_color)

without them, the colors are passed in as hex instead of rgb.

Currently looking to see in which version of matplotlib (and/or lifelines) this behavior changed.

jburos commented 7 years ago

Confirmed with lifelines v 0.9.1.0 and 0.9.2.0 that the previous behavior works & two lines are required in order to avoid an error.

With 0.9.3.2 through 0.11.xx, these two lines cause an error & need to be removed.

jburos commented 7 years ago

Doesn't appear to be mentioned in lifelines changelog.md, but fix likely involves hard-coding lifelines version >= 0.9.3.2 & removing these two lines.