0

I have the following plot code in seaborn

import seaborn as sns
import matplotlib.pyplot as plt

iris= sns.load_dataset("iris")

g= sns.pairplot(iris, 
             x_vars=["sepal_width", "sepal_length"],
            y_vars=["petal_width"])

This produces the following output

enter image description here

Now I am trying to add a vertical line at x=3 on both plots

I have tried using plt.axvline(x=3, ls='--', linewidth=3, color='red') however that draws the line only on the last plot, as shown below

enter image description here

How can I have the vertical line drawn on both plots?

I have tried g.map_offdiag(plt.axvline(x=1, ls='--', linewidth=3, color='red')) and the g.map() variant, however I get the following error.

TypeError                                 Traceback (most recent call last)
<ipython-input-12-612fcf2a7fef> in <module>
      9 
     10 # plt.axvline(x=3, ls='--', linewidth=3, color='red')
---> 11 g.map_offdiag(plt.axvline(x=1, ls='--', linewidth=3, color='red'))
     12 
     13 

~/PycharmProjects/venv/lib/python3.8/site-packages/seaborn/axisgrid.py in map_offdiag(self, func, **kwargs)
   1318                     if x_var != y_var:
   1319                         indices.append((i, j))
-> 1320             self._map_bivariate(func, indices, **kwargs)
   1321         return self
   1322 

~/PycharmProjects/venv/lib/python3.8/site-packages/seaborn/axisgrid.py in _map_bivariate(self, func, indices, **kwargs)
   1463             if ax is None:  # i.e. we are in corner mode
   1464                 continue
-> 1465             self._plot_bivariate(x_var, y_var, ax, func, **kws)
   1466         self._add_axis_labels()
   1467 

~/PycharmProjects/venv/lib/python3.8/site-packages/seaborn/axisgrid.py in _plot_bivariate(self, x_var, y_var, ax, func, **kwargs)
   1471     def _plot_bivariate(self, x_var, y_var, ax, func, **kwargs):
   1472         """Draw a bivariate plot on the specified axes."""
-> 1473         if "hue" not in signature(func).parameters:
   1474             self._plot_bivariate_iter_hue(x_var, y_var, ax, func, **kwargs)
   1475             return

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/inspect.py in signature(obj, follow_wrapped)
   3091 def signature(obj, *, follow_wrapped=True):
   3092     """Get a signature object for the passed callable."""
-> 3093     return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
   3094 
   3095 

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/inspect.py in from_callable(cls, obj, follow_wrapped)
   2840     def from_callable(cls, obj, *, follow_wrapped=True):
   2841         """Constructs Signature for the given callable object."""
-> 2842         return _signature_from_callable(obj, sigcls=cls,
   2843                                         follow_wrapper_chains=follow_wrapped)
   2844 

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/inspect.py in _signature_from_callable(obj, follow_wrapper_chains, skip_bound_arg, sigcls)
   2214 
   2215     if not callable(obj):
-> 2216         raise TypeError('{!r} is not a callable object'.format(obj))
   2217 
   2218     if isinstance(obj, types.MethodType):

TypeError: <matplotlib.lines.Line2D object at 0x1287cc580> is not a callable object

Any suggestions?

1 Answers1

2

The easiest way is to loop through the axes and call axvline() on each of them. Note that .ravel() converts the 2D array of axes to a 1D array.

import seaborn as sns
import matplotlib.pyplot as plt

iris = sns.load_dataset("iris")

g = sns.pairplot(iris,
                 x_vars=["sepal_width", "sepal_length"],
                 y_vars=["petal_width"])
for ax in g.axes.ravel():
    ax.axvline(x=3, ls='--', linewidth=3, c='red')
plt.show()

resulting plot

To use g.map() or its variants, the first parameter needs to be a function (without calling), followed by the parameters. So, in theory it would be g.map(plt.axvline, x=1, ls='--', linewidth=3, color='red'). But for a pairplot, the mapped function gets called with an x and y parameter from the pairplot, which conflict with the x as parameter for axvline.

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • yes, I did try the `g.map()` argument variant as you have written but I was getting an error relating to multiple x values. Now I see why. thanks! – Behzad Rowshanravan Mar 01 '21 at 23:22