diff --git a/doc/ref/plotting_options/styling.ipynb b/doc/ref/plotting_options/styling.ipynb index 1198124aa..9d9550caf 100644 --- a/doc/ref/plotting_options/styling.ipynb +++ b/doc/ref/plotting_options/styling.ipynb @@ -311,6 +311,54 @@ "plot2 = df.hvplot(group_label=\"Company\", grid=True, width=400, title=\"grid=True\")\n", "(plot1 + plot2).cols(1)" ] + }, + { + "cell_type": "markdown", + "id": "56cdf3e2", + "metadata": {}, + "source": [ + "To show grid only on the x-axis, use ``grid='x'``. To show grid only on the y-axis, use ``grid='y'``. To change the grid line style, suffix with ``'dashed'``, ``'dotted'``, or ``'dashdot'``, e.g. ``grid='x-dashed'``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e38dee4", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "df = hvplot.sampledata.stocks(\"pandas\", engine_kwargs={\"index_col\" : \"date\"})\n", + "\n", + "plot1 = df.hvplot(group_label=\"Company\", grid='x', width=400, title=\"grid='x'\")\n", + "plot2 = df.hvplot(group_label=\"Company\", grid='y-dashed', width=400, title=\"grid='y-dashed'\")\n", + "(plot1 + plot2).cols(1)" + ] + }, + { + "cell_type": "markdown", + "id": "59315b89", + "metadata": {}, + "source": [ + " A dictionary of grid style options may also be supplied, e.g. for bokeh, ``{'grid_line_color': 'red', 'grid_line_alpha': 0.5}``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3b095ba", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "df = hvplot.sampledata.stocks(\"pandas\", engine_kwargs={\"index_col\" : \"date\"})\n", + "\n", + "plot1 = df.hvplot(group_label=\"Company\", grid={'grid_line_color': 'red', 'grid_line_alpha': 0.5}, width=400, title=\"grid=dict\")\n", + "plot2 = df.hvplot(group_label=\"Company\", grid={'xgrid_line_color': 'green', 'xgrid_line_alpha': 0.5}, width=400, title=\"grid=dict (x-axis only)\")\n", + "(plot1 + plot2).cols(1)" + ] } ], "metadata": { diff --git a/hvplot/converter.py b/hvplot/converter.py index 361b55da5..33e9b6db9 100644 --- a/hvplot/converter.py +++ b/hvplot/converter.py @@ -475,8 +475,13 @@ class HoloViewsConverter: fontsize : number or dict or None, default=None Set title, label and legend text to the same fontsize. Finer control by using a dict: ``{'title': '15pt', 'ylabel': '5px', 'ticks': 20}``. - grid : bool or None, default=None - Whether to show a grid. + grid : bool, str, dict, or None, default=None + Whether to show a grid. If True, shows grid on both axes. + If ``'x'`` or ``'y'``, shows grid only on the specified axis. + Suffix with ``'dashed'``, ``'dotted'``, or ``'dashdot'`` + to change the grid line style, e.g. ``'x-dashed'``. + A dictionary of grid style options may also be supplied, e.g. for bokeh, + ``{'grid_line_color': 'red', 'grid_line_alpha': 0.5}``. Resampling Options ------------------ @@ -1059,7 +1064,28 @@ def __init__( plot_opts['logy'] = logy if grid is not None: - plot_opts['show_grid'] = grid + if isinstance(grid, str): + gridstyle = {} + axis = grid[0] + other_axis = 'x' if axis == 'y' else 'y' + if len(grid) > 1: + line_dash = grid[1:].lstrip('-').lstrip('.').lstrip('_') + line_dash_key = ( + f'{axis}grid_line_dash' + if self._backend_compat == 'bokeh' + else f'{axis}grid_linestyle' + ) + gridstyle[line_dash_key] = line_dash + line_alpha_key = ( + f'{other_axis}grid_line_alpha' + if self._backend_compat == 'bokeh' + else f'{other_axis}grid_alpha' + ) + gridstyle[line_alpha_key] = 0 + plot_opts['gridstyle'] = gridstyle + elif isinstance(grid, dict): + plot_opts['gridstyle'] = grid + plot_opts['show_grid'] = bool(grid) if legend is not None: plot_opts['show_legend'] = bool(legend) diff --git a/hvplot/tests/testoptions.py b/hvplot/tests/testoptions.py index b20676555..9cc22110d 100644 --- a/hvplot/tests/testoptions.py +++ b/hvplot/tests/testoptions.py @@ -635,6 +635,38 @@ def test_legend_opts(self, df, backend): opts = Store.lookup_options(backend, plot, 'plot') assert opts.kwargs['legend_opts'] == lo + @pytest.mark.parametrize('grid_bool', [True, False]) + def test_grid_boolean(self, df, backend, grid_bool): + plot = df.hvplot('x', 'y', grid=grid_bool) + opts = Store.lookup_options(backend, plot, 'plot') + assert opts.kwargs['grid'] is grid_bool + + def test_grid_x(self, df, backend): + plot = df.hvplot('x', 'y', grid='x') + opts = Store.lookup_options(backend, plot, 'plot') + assert opts.kwargs['grid'] is True + assert opts.kwargs['gridstyle'] == {'ygrid_line_alpha': 0} + + def test_grid_y(self, df, backend): + plot = df.hvplot('x', 'y', grid='y') + opts = Store.lookup_options(backend, plot, 'plot') + assert opts.kwargs['grid'] is True + assert opts.kwargs['gridstyle'] == {'xgrid_line_alpha': 0} + + @pytest.mark.parametrize('grid_str', ['x-dashed', 'xdashed', 'x.dashed', 'x_dashed']) + def test_grid_line_dash(self, df, backend, grid_str): + plot = df.hvplot('x', 'y', grid=grid_str) + opts = Store.lookup_options(backend, plot, 'plot') + assert opts.kwargs['grid'] is True + assert opts.kwargs['gridstyle'] == {'ygrid_line_alpha': 0, 'xgrid_line_dash': 'dashed'} + + def test_grid_line_dict(self, df, backend): + grid_dict = {'ygrid_line_alpha': 0, 'xgrid_line_dash': 'dashed'} + plot = df.hvplot('x', 'y', grid=grid_dict) + opts = Store.lookup_options(backend, plot, 'plot') + assert opts.kwargs['grid'] is True + assert opts.kwargs['gridstyle'] == grid_dict + @pytest.fixture(scope='module') def da():