Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matplotlib version [Urgent, maybe] #236

Closed
sahiljhawar opened this issue Sep 17, 2023 · 13 comments
Closed

Matplotlib version [Urgent, maybe] #236

sahiljhawar opened this issue Sep 17, 2023 · 13 comments

Comments

@sahiljhawar
Copy link

With Matplotlib >= 3.8 and Python >=3.9, corner.py raises the AttributeError: Polygon.set() got an unexpected keyword argument 'markersize'. To avoid this either corner.py needs to updated or Matplotlib should be restricted to < 3.8.

Here is an extended version of the error:

Error (Click to expand)
nmma/em/analysis.py:911: in main
  analysis(args)
nmma/em/analysis.py:705: in analysis
  result.plot_corner(parameters=injection)
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/bilby/core/utils/plotting.py:65: in wrapper_decorator
  return func(*args, **kwargs)
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/bilby/core/result.py:1260: in plot_corner
  fig = corner.corner(xs, **kwargs)
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/corner/corner.py:280: in corner
  return arviz_corner(
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/corner/arviz_corner.py:136: in arviz_corner
  fig = corner_impl(
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/corner/core.py:370: in corner_impl
  hist2d(
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/corner/core.py:755: in hist2d
  ax.plot(x, y, "o", zorder=-1, rasterized=True, **data_kwargs)
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/axes/_axes.py:1721: in plot
  lines = [*self._get_lines(self, *args, data=data, **kwargs)]
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/axes/_base.py:303: in __call__
  yield from self._plot_args(
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/axes/_base.py:539: in _plot_args
  return [l[0] for l in result]
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/axes/_base.py:539: in <listcomp>
  return [l[0] for l in result]
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/axes/_base.py:532: in <genexpr>
  result = (make_artist(axes, x[:, j % ncx], y[:, j % ncy], kw,
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/axes/_base.py:3[98](https://github.com/nuclear-multimessenger-astronomy/nmma/actions/runs/6208576180/job/16858201719#step:11:99): in _makefill
  seg.set(**kwargs)
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/artist.py:147: in <lambda>
  cls.set = lambda self, **kwargs: Artist.set(self, **kwargs)
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/artist.py:1227: in set
  return self._internal_update(cbook.normalize_kwargs(kwargs, self))
/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/artist.py:1219: in _internal_update
  return self._update_props(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <matplotlib.patches.Polygon object at 0x7fe5b3050[99](https://github.com/nuclear-multimessenger-astronomy/nmma/actions/runs/6208576180/job/16858201719#step:11:100)0>
props = {'alpha': 0.1, 'color': '#0072C1', 'label': None, 'markeredgecolor': 'none', ...}
errfmt = '{cls.__name__}.set() got an unexpected keyword argument {prop_name!r}'

  def _update_props(self, props, errfmt):
      """
      Helper for `.Artist.set` and `.Artist.update`.
  
      *errfmt* is used to generate error messages for invalid property
      names; it gets formatted with ``type(self)`` and the property name.
      """
      ret = []
      with cbook._setattr_cm(self, eventson=False):
          for k, v in props.items():
              # Allow attributes we want to be able to update through
              # art.update, art.set, setp.
              if k == "axes":
                  ret.append(setattr(self, k, v))
              else:
                  func = getattr(self, f"set_{k}", None)
                  if not callable(func):
>                       raise AttributeError(
                          errfmt.format(cls=type(self), prop_name=k))
E                       AttributeError: Polygon.set() got an unexpected keyword argument 'markersize'

/opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/matplotlib/artist.py:[119](https://github.com/nuclear-multimessenger-astronomy/nmma/actions/runs/6208576180/job/16858201719#step:11:120)3: AttributeError
@dfm
Copy link
Owner

dfm commented Sep 17, 2023

This looks to me like a bilby problem, not a corner issue. Please see if you can reproduce the issue directly with corner. Thanks!

@sahiljhawar
Copy link
Author

I checked the relevant Bilby code, I can affirm that issue is not from there. The markersize or ms value is directly passed from here: https://github.com/dfm/corner.py/blob/701d6c4a91d226c32432753194d5d19eb8559caf/src/corner/core.py#L755C10-L755C10 . However the issue also cannot be directly reproduced by the corner.

@dfm
Copy link
Owner

dfm commented Sep 18, 2023

However the issue also cannot be directly reproduced by the corner.

But this seems inconsistent, if the issue only appears deep in wrapped code!

I'm going to close this issue since it can't be reproduced, but please feel free to reopen with a simple example that doesn't rely on bilby or another downstream package. Thanks!

@dfm dfm closed this as completed Sep 18, 2023
@mattpitkin
Copy link
Contributor

Just to note that I see this same problem too (using Matplotlib v3.8.0 and corner v2.2.2), but also going through gravitational-wave code, in this case accessing corner through pesummary. It doesn't seem to be a problem when using Matplotlib v3.7.2 and corner v2.2.1.

@dfm
Copy link
Owner

dfm commented Sep 20, 2023

Thanks! I'd love to see this reproduced without a wrapper because I haven't been able to reproduce locally. Happy to investigate if we can!

@mattpitkin
Copy link
Contributor

I can't reproduce it with just corner either - I've tried with the same input kwargs that are being passed in my code that goes through pesummary. In fact, if I just use the pesummary _make_corner_plot function on its own (which calls corner) in an ipython terminal I can't reproduce the error either. I'm actually calling _make_corner_plot through function in CWInPy, which adds another layer. So, something in bilby/CWInPy, or one of their other dependencies must be setting something that causes the matplotlib internals to thing a markersize argument has been passed. I'll try and delve deeper.

@sahiljhawar
Copy link
Author

sahiljhawar commented Sep 20, 2023

But markersize is a valid argument for both ax.plot() and plt.plot() if the style is anything other than continous line. The error is raised only if both ms and markersize are passed.

@mattpitkin Also, markersize or ms is never explicitly passed to _make_corner_plot, or plot_corner in my case.

@mattpitkin
Copy link
Contributor

mattpitkin commented Sep 20, 2023

Ok, so I have more of a hint towards the problem. The following does not cause an error:

import numpy as np
from corner import corner

data = np.random.randn(500, 4)
fig = corner(data)

However, if I import in something from GWPy, e.g., GW_OBSERVATORY_COLORS (this is something that I import in CWInPy), it errors:

from gwpy.plot.colors import GW_OBSERVATORY_COLORS
fig = corner(data)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[13], line 1
----> 1 fig = corner(data)

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/corner/corner.py:248, in corner(data, bins, range, axes_scale, weights, color, hist_bin_factor, smooth, smooth1d, labels, label_kwargs, titles, show_titles, title_quantiles, title_fmt, title_kwargs, truths, truth_color, scale_hist, quantiles, verbose, fig, max_n_ticks, top_ticks, use_math_text, reverse, labelpad, hist_kwargs, group, var_names, filter_vars, coords, divergences, divergences_kwargs, labeller, **hist2d_kwargs)
    236     if (
    237         var_names is not None
    238         or filter_vars is not None
   (...)
    242         or labeller is not None
    243     ):
    244         logging.warning(
    245             "Please install arviz to use the advanced features of corner"
    246         )
--> 248     return corner_impl(
    249         data,
    250         bins=bins,
    251         range=range,
    252         axes_scale=axes_scale,
    253         weights=weights,
    254         color=color,
    255         hist_bin_factor=hist_bin_factor,
    256         smooth=smooth,
    257         smooth1d=smooth1d,
    258         labels=labels,
    259         label_kwargs=label_kwargs,
    260         titles=titles,
    261         show_titles=show_titles,
    262         title_quantiles=title_quantiles,
    263         title_fmt=title_fmt,
    264         title_kwargs=title_kwargs,
    265         truths=truths,
    266         truth_color=truth_color,
    267         scale_hist=scale_hist,
    268         quantiles=quantiles,
    269         verbose=verbose,
    270         fig=fig,
    271         max_n_ticks=max_n_ticks,
    272         top_ticks=top_ticks,
    273         use_math_text=use_math_text,
    274         reverse=reverse,
    275         labelpad=labelpad,
    276         hist_kwargs=hist_kwargs,
    277         **hist2d_kwargs,
    278     )
    280 return arviz_corner(
    281     data,
    282     bins=bins,
   (...)
    316     **hist2d_kwargs,
    317 )

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/corner/core.py:370, in corner_impl(xs, bins, range, axes_scale, weights, color, hist_bin_factor, smooth, smooth1d, labels, label_kwargs, titles, show_titles, title_fmt, title_kwargs, truths, truth_color, scale_hist, quantiles, title_quantiles, verbose, fig, max_n_ticks, top_ticks, use_math_text, reverse, labelpad, hist_kwargs, **hist2d_kwargs)
    367 if hasattr(y, "compressed"):
    368     y = y.compressed()
--> 370 hist2d(
    371     y,
    372     x,
    373     ax=ax,
    374     range=[range[j], range[i]],
    375     axes_scale=[axes_scale[j], axes_scale[i]],
    376     weights=weights,
    377     color=color,
    378     smooth=smooth,
    379     bins=[bins[j], bins[i]],
    380     new_fig=new_fig,
    381     force_range=force_range,
    382     **hist2d_kwargs,
    383 )
    385 if max_n_ticks == 0:
    386     ax.xaxis.set_major_locator(NullLocator())

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/corner/core.py:755, in hist2d(x, y, bins, range, axes_scale, weights, levels, smooth, ax, color, quiet, plot_datapoints, plot_density, plot_contours, no_fill_contours, fill_contours, contour_kwargs, contourf_kwargs, data_kwargs, pcolor_kwargs, new_fig, force_range, **kwargs)
    753     data_kwargs["mec"] = data_kwargs.get("mec", "none")
    754     data_kwargs["alpha"] = data_kwargs.get("alpha", 0.1)
--> 755     ax.plot(x, y, "o", zorder=-1, rasterized=True, **data_kwargs)
    757 # Plot the base fill to hide the densest data points.
    758 if (plot_contours or plot_density) and not no_fill_contours:

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/axes/_axes.py:1721, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
   1478 """
   1479 Plot y versus x as lines and/or markers.
   1480 
   (...)
   1718 (``'green'``) or hex strings (``'#008000'``).
   1719 """
   1720 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1721 lines = [*self._get_lines(self, *args, data=data, **kwargs)]
   1722 for line in lines:
   1723     self.add_line(line)

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/axes/_base.py:303, in _process_plot_var_args.__call__(self, axes, data, *args, **kwargs)
    301     this += args[0],
    302     args = args[1:]
--> 303 yield from self._plot_args(
    304     axes, this, kwargs, ambiguous_fmt_datakey=ambiguous_fmt_datakey)

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/axes/_base.py:539, in _process_plot_var_args._plot_args(self, axes, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)
    537     return list(result)
    538 else:
--> 539     return [l[0] for l in result]

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/axes/_base.py:539, in <listcomp>(.0)
    537     return list(result)
    538 else:
--> 539     return [l[0] for l in result]

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/axes/_base.py:532, in <genexpr>(.0)
    529 else:
    530     labels = [label] * n_datasets
--> 532 result = (make_artist(axes, x[:, j % ncx], y[:, j % ncy], kw,
    533                       {**kwargs, 'label': label})
    534           for j, label in enumerate(labels))
    536 if return_kwargs:
    537     return list(result)

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/axes/_base.py:398, in _process_plot_var_args._makefill(self, axes, x, y, kw, kwargs)
    392 self._setdefaults(default_dict, kwargs)
    394 seg = mpatches.Polygon(np.column_stack((x, y)),
    395                        facecolor=facecolor,
    396                        fill=kwargs.get('fill', True),
    397                        closed=kw['closed'])
--> 398 seg.set(**kwargs)
    399 return seg, kwargs

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/artist.py:147, in Artist.__init_subclass__.<locals>.<lambda>(self, **kwargs)
    139 if not hasattr(cls.set, '_autogenerated_signature'):
    140     # Don't overwrite cls.set if the subclass or one of its parents
    141     # has defined a set method set itself.
    142     # If there was no explicit definition, cls.set is inherited from
    143     # the hierarchy of auto-generated set methods, which hold the
    144     # flag _autogenerated_signature.
    145     return
--> 147 cls.set = lambda self, **kwargs: Artist.set(self, **kwargs)
    148 cls.set.__name__ = "set"
    149 cls.set.__qualname__ = f"{cls.__qualname__}.set"

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/artist.py:1227, in Artist.set(self, **kwargs)
   1223 def set(self, **kwargs):
   1224     # docstring and signature are auto-generated via
   1225     # Artist._update_set_signature_and_docstring() at the end of the
   1226     # module.
-> 1227     return self._internal_update(cbook.normalize_kwargs(kwargs, self))

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/artist.py:1219, in Artist._internal_update(self, kwargs)
   1212 def _internal_update(self, kwargs):
   1213     """
   1214     Update artist properties without prenormalizing them, but generating
   1215     errors as if calling `set`.
   1216 
   1217     The lack of prenormalization is to maintain backcompatibility.
   1218     """
-> 1219     return self._update_props(
   1220         kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
   1221         "{prop_name!r}")

File ~/.conda/envs/cwinpy/lib/python3.9/site-packages/matplotlib/artist.py:1193, in Artist._update_props(self, props, errfmt)
   1191             func = getattr(self, f"set_{k}", None)
   1192             if not callable(func):
-> 1193                 raise AttributeError(
   1194                     errfmt.format(cls=type(self), prop_name=k))
   1195             ret.append(func(v))
   1196 if ret:

AttributeError: Polygon.set() got an unexpected keyword argument 'markersize'

These use:

  • Python 3.9.18
  • corner v2.2.2
  • matplotlib v3.8.0
  • gwpy v3.0.5

cc @duncanmmacleod

@dfm
Copy link
Owner

dfm commented Sep 21, 2023

Good debugging! It looks like (by default) importing gwpy updates the matplotlib rcParams, which must somehow be causing both ms and markersize to be passed to plot?
Corner explicitly sets ms (and mec) (rather than markersize), but it's not clear to me why such a collision would depend on the version of matplotlib!

@sahiljhawar
Copy link
Author

But in the rc.py, there's no markersize or ms.

but it's not clear to me why such a collision would depend on the version of matplotlib!

  • Maybe there had been significant API changes which is not interacting well.

@ColmTalbot
Copy link

I think the markersize issue is a red herring. We have another error in Bilby that I think is more informative. Something is going wrong with the type that is being returned leading to having Polygon rather than Line2D. I agree that this is an issue with gwpy/matplotlib interaction. I suspect that the underlying issue is resolved in this commit that hasn't yet been released.

@mattpitkin
Copy link
Contributor

@ColmTalbot I can confirm that, if I install GWPy from source so that it includes gwpy/gwpy#1661, then the problem goes away. So, we'll just have to wait for the next GWPy release.

@dfm
Copy link
Owner

dfm commented Sep 21, 2023

Thanks all for tracking this down!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants