Repository: holoviz/hvplot

Issue:
Allow specifying keyword arguments for diagonal
#### Is your feature request related to a problem? Please describe.
Although it is possible to provide keyword arguments that are passed to off-diagonal (by default scatter) plots, it isn't possible to do the same with the diagonal (by default histogram) plots. This makes it hard to set things like the bin size for the histograms.

#### Describe the solution you'd like
An argument for the function, taking a dict, which is set as the keyword arguments for the diagonal plots.  Perhaps `diagonal_kwds` or `diag_kwds`.  So, for example, `hvplot.scatter_matrix(data, diag_kwds={'bins': 100})`. 

#### Describe alternatives you've considered
Manually specifying the options to the grid is possible, but cumbersome since it requires calculating which grid elements are the diagonals.

#### Additional context
The pandas `scatter_matrix` provides separate arguments to specify options for the diagonal and off-diagonal plots.  It uses `hist_kwds` and `density_kwds`, for 'hist' and 'kde' plots, respectively. This seems redundant to me since you an only ever use one or the other.



Discussion:

Resolving patch:
diff --git a/hvplot/plotting/scatter_matrix.py b/hvplot/plotting/scatter_matrix.py
--- a/hvplot/plotting/scatter_matrix.py
+++ b/hvplot/plotting/scatter_matrix.py
@@ -7,25 +7,52 @@
 
 
 @with_hv_extension
-def scatter_matrix(data, c=None, chart='scatter', diagonal='hist', alpha=0.5, **kwds):
+def scatter_matrix(data, c=None, chart='scatter', diagonal='hist',
+                   alpha=0.5, nonselection_alpha=0.1,
+                   tools=None, cmap=None, colormap=None,
+                   diagonal_kwds=None, hist_kwds=None, density_kwds=None,
+                   **kwds):
     """
     Scatter matrix of numeric columns.
 
+    A scatter_matrix shows all the pairwise relationships between the columns.
+    Each non-diagonal plots the corresponding columns against each other,
+    while the diagonal plot shows the distribution of each individual column.
+
+    This function is closely modelled on :func:`pandas.plotting.scatter_matrix`.
+
     Parameters:
     -----------
     data: DataFrame
+        The data to plot. Every column is compared to every other column.
     c: str, optional
         Column to color by
     chart: str, optional
-        Chart type (one of 'scatter', 'bivariate', 'hexbin')
+        Chart type for the off-diagonal plots (one of 'scatter', 'bivariate', 'hexbin')
     diagonal: str, optional
-        Chart type for the diagonal (one of 'hist', 'kde')
-    kwds: hvplot.scatter options, optional
+        Chart type for the diagonal plots (one of 'hist', 'kde')
+    alpha: float, optional
+        Transparency level for the off-diagonal plots
+    nonselection_alpha: float, optional
+        Transparency level for nonselected object in the off-diagonal plots
+    tools: str or list of str, optional
+        Interaction tools to include
+        Defaults are 'box_select' and 'lasso_select'
+    cmap/colormap: str or colormap object, optional
+        Colormap to use for off-diagonal plots
+        Default is `Category10 <https://github.com/d3/d3-3.x-api-reference/blob/master/Ordinal-Scales.md#category10>`.
+    diagonal_kwds/hist_kwds/density_kwds: dict, optional
+        Keyword options for the diagonal plots
+    kwds: Keyword options for the off-diagonal plots, optional
 
     Returns:
     --------
     obj : HoloViews object
         The HoloViews representation of the plot.
+
+    See Also
+    --------
+        :func:`pandas.plotting.scatter_matrix` : Equivalent pandas function.
     """
     data = _hv.Dataset(data)
     supported = list(HoloViewsConverter._kind_mapping)
@@ -38,9 +65,12 @@ def scatter_matrix(data, c=None, chart='scatter', diagonal='hist', alpha=0.5, **
     diagonal = HoloViewsConverter._kind_mapping[diagonal]
     chart = HoloViewsConverter._kind_mapping[chart]
 
-    colors = _hv.plotting.util.process_cmap('Category10', categorical=True)
-    chart_opts = dict(alpha=alpha, cmap=colors, tools=['box_select', 'lasso_select'],
-                      nonselection_alpha=0.1, **kwds)
+    if cmap and colormap:
+        raise TypeError("Only specify one of `cmap` and `colormap`.")
+    colors = cmap or colormap or _hv.plotting.util.process_cmap('Category10', categorical=True)
+    tools = tools or ['box_select', 'lasso_select']
+    chart_opts = dict(alpha=alpha, cmap=colors, tools=tools,
+                      nonselection_alpha=nonselection_alpha, **kwds)
 
     grid = _hv.operation.gridmatrix(data, diagonal_type=diagonal, chart_type=chart)
     if c:
@@ -52,5 +82,12 @@ def scatter_matrix(data, c=None, chart='scatter', diagonal='hist', alpha=0.5, **
         grid = (grid * groups).map(lambda x: x.get(0) if isinstance(x.get(0), chart) else x.get(1),
                                    _hv.Overlay)
 
-    diagonal_opts = {'fill_color': _hv.Cycle(values=colors)}
+    if (diagonal_kwds and hist_kwds) or \
+       (diagonal_kwds and density_kwds) or \
+       (hist_kwds and density_kwds):
+        raise TypeError('Specify at most one of `diagonal_kwds`, `hist_kwds`, or '
+                        '`density_kwds`.')
+
+    diagonal_kwds = diagonal_kwds or hist_kwds or density_kwds or {}
+    diagonal_opts = dict(fill_color=_hv.Cycle(values=colors), **diagonal_kwds)
     return grid.options({chart.__name__: chart_opts, diagonal.__name__: diagonal_opts})


Test patch: