Repository: arviz-devs/arviz

Issue:
plot_rank ignores backend_kwargs

Using `plot_rank` on many a trace with many coefficients can require changing the line widths and marker sizes (e.g. when using `kind="vlines"`). 

This usage however has no effect:

`az.plot_rank(many_coefficient_trace, backend_kwargs={'linewidth':0.5, 'markersize':1, 's':1})`

The docstring says 

> These are kwargs specific to the backend being used. For additional documentation check the plotting method of the backend.

, which seems to suggest passing this dictionary is the correct usage. How can this be changed to accept kwargs, or could an example usage be added?




Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=h1) Report
> Merging [#1419](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=desc) into [master](https://codecov.io/gh/arviz-devs/arviz/commit/86b4aa9e98c98b115aeb09df43ef1c7c9237a685?el=desc) will **decrease** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/arviz-devs/arviz/pull/1419/graphs/tree.svg?width=650&height=150&src=pr&token=KZTdQCEf7t)](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1419      +/-   ##
==========================================
- Coverage   91.60%   91.60%   -0.01%     
==========================================
  Files         105      105              
  Lines       11090    11120      +30     
==========================================
+ Hits        10159    10186      +27     
- Misses        931      934       +3     
```


| [Impacted Files](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [arviz/plots/rankplot.py](https://codecov.io/gh/arviz-devs/arviz/pull/1419/diff?src=pr&el=tree#diff-YXJ2aXovcGxvdHMvcmFua3Bsb3QucHk=) | `90.32% <ø> (ø)` | |
| [arviz/plots/backends/bokeh/rankplot.py](https://codecov.io/gh/arviz-devs/arviz/pull/1419/diff?src=pr&el=tree#diff-YXJ2aXovcGxvdHMvYmFja2VuZHMvYm9rZWgvcmFua3Bsb3QucHk=) | `94.66% <100.00%> (+1.22%)` | :arrow_up: |
| [arviz/plots/backends/matplotlib/rankplot.py](https://codecov.io/gh/arviz-devs/arviz/pull/1419/diff?src=pr&el=tree#diff-YXJ2aXovcGxvdHMvYmFja2VuZHMvbWF0cGxvdGxpYi9yYW5rcGxvdC5weQ==) | `96.96% <100.00%> (+0.96%)` | :arrow_up: |
| [arviz/stats/stats\_utils.py](https://codecov.io/gh/arviz-devs/arviz/pull/1419/diff?src=pr&el=tree#diff-YXJ2aXovc3RhdHMvc3RhdHNfdXRpbHMucHk=) | `94.91% <0.00%> (-0.68%)` | :arrow_down: |
| [arviz/stats/stats.py](https://codecov.io/gh/arviz-devs/arviz/pull/1419/diff?src=pr&el=tree#diff-YXJ2aXovc3RhdHMvc3RhdHMucHk=) | `96.05% <0.00%> (-0.17%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=footer). Last update [86b4aa9...19f6f17](https://codecov.io/gh/arviz-devs/arviz/pull/1419?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7da3e3b..c82f6d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
 * Added `to_dataframe` method to InferenceData ([1395](https://github.com/arviz-devs/arviz/pull/1395))
 * Added `__getitem__` magic to InferenceData ([1395](https://github.com/arviz-devs/arviz/pull/1395))
 * Added group argument to summary ([1408](https://github.com/arviz-devs/arviz/pull/1408))
+* Add `ref_line`, `bar`, `vlines` and `marker_vlines` kwargs to `plot_rank` ([1419](https://github.com/arviz-devs/arviz/pull/1419))
 * Add observed argument to (un)plot observed data in `plot_ppc` ([1422](https://github.com/arviz-devs/arviz/pull/1422))
 
 ### Maintenance and fixes
@@ -14,6 +15,7 @@
 * Fixed a typo found in an error message raised in `distplot.py` ([1414](https://github.com/arviz-devs/arviz/pull/1414))
 * Fix typo in `loo_pit` extraction of log likelihood ([1418](https://github.com/arviz-devs/arviz/pull/1418))
 * Have `from_pystan` store attrs as strings to allow netCDF storage ([1417](https://github.com/arviz-devs/arviz/pull/1417))
+* Remove ticks and spines in `plot_violin`  ([1426 ](https://github.com/arviz-devs/arviz/pull/1426))
 
 ### Deprecation
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0097518..c10bef9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,6 +9,8 @@ There are 4 main ways of contributing to the ArviZ project (in descending order
 * Contributing or improving the documentation (`docs`) or examples (`arviz/examples`)
 * Submitting issues related to bugs or desired enhancements
 
+This doc plus extra guidance is also available on [ArviZ documentation](https://arviz-devs.github.io/arviz/contributing/index.html)
+
 # Opening issues
 
 We appreciate being notified of problems with the existing ArviZ code. We prefer that issues be filed the on [Github Issue Tracker](https://github.com/arviz-devs/arviz/issues), rather than on social media or by direct email to the developers.
@@ -80,7 +82,7 @@ If changes are made to a method documented in the
 [ArviZ API Guide](https://numpydoc.readthedocs.io/en/latest/format.html)
 please consider adding inline documentation examples.
 `az.plot_posterior` is a particularly
-[good example](https://arviz-devs.github.io/arviz/generated/arviz.plot_posterior.html#arviz.plot_posterior).
+[good example](https://arviz-devs.github.io/arviz/api/generated/arviz.plot_posterior.html#arviz.plot_posterior).
 
 
 ## Steps
diff --git a/README.md b/README.md
index f23c8d9..cb86427 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ ArviZ also has a Julia wrapper available [ArviZ.jl](https://arviz-devs.github.io
 ## Documentation
 
 The ArviZ documentation can be found in the [official docs](https://arviz-devs.github.io/arviz/index.html).
-First time users may find the [quickstart](https://arviz-devs.github.io/arviz/notebooks/Introduction.html)
+First time users may find the [quickstart](https://arviz-devs.github.io/arviz/getting_started/Introduction.html)
 to be helpful. Additional guidance can be found in the
 [usage documentation](https://arviz-devs.github.io/arviz/usage.html).
 
diff --git a/arviz/plots/backends/bokeh/rankplot.py b/arviz/plots/backends/bokeh/rankplot.py
index d8f0d77..9b287bb 100644
--- a/arviz/plots/backends/bokeh/rankplot.py
+++ b/arviz/plots/backends/bokeh/rankplot.py
@@ -23,10 +23,31 @@ def plot_rank(
     colors,
     ref_line,
     labels,
+    ref_line_kwargs,
+    bar_kwargs,
+    vlines_kwargs,
+    marker_vlines_kwargs,
     backend_kwargs,
     show,
 ):
     """Bokeh rank plot."""
+    if ref_line_kwargs is None:
+        ref_line_kwargs = {}
+    ref_line_kwargs.setdefault("line_dash", "dashed")
+    ref_line_kwargs.setdefault("line_color", "black")
+
+    if bar_kwargs is None:
+        bar_kwargs = {}
+    bar_kwargs.setdefault("line_color", "white")
+
+    if vlines_kwargs is None:
+        vlines_kwargs = {}
+    vlines_kwargs.setdefault("line_width", 2)
+    vlines_kwargs.setdefault("line_dash", "solid")
+
+    if marker_vlines_kwargs is None:
+        marker_vlines_kwargs = {}
+
     if backend_kwargs is None:
         backend_kwargs = {}
 
@@ -62,6 +83,7 @@ def plot_rank(
         gap = 1
         width = bin_ary[1] - bin_ary[0]
 
+        bar_kwargs.setdefault("width", width)
         # Center the bins
         bin_ary = (bin_ary[1:] + bin_ary[:-1]) / 2
 
@@ -74,34 +96,30 @@ def plot_rank(
                     x=bin_ary,
                     top=y_ticks[-1] + counts,
                     bottom=y_ticks[-1],
-                    width=width,
                     fill_color=colors[idx],
-                    line_color="white",
+                    **bar_kwargs,
                 )
                 if ref_line:
-                    hline = Span(
-                        location=y_ticks[-1] + counts.mean(), line_dash="dashed", line_color="black"
-                    )
+                    hline = Span(location=y_ticks[-1] + counts.mean(), **ref_line_kwargs)
                     ax.add_layout(hline)
             if labels:
                 ax.yaxis.axis_label = "Chain"
         elif kind == "vlines":
             ymin = np.full(len(all_counts), all_counts.mean())
             for idx, counts in enumerate(all_counts):
-                ax.circle(bin_ary, counts, fill_color=colors[idx], line_color=colors[idx])
-
-                x_locations = [(bin, bin) for bin in bin_ary]
-                y_locations = [(ymin[idx], counts_) for counts_ in counts]
-                ax.multi_line(
-                    x_locations,
-                    y_locations,
-                    line_dash="solid",
+                ax.circle(
+                    bin_ary,
+                    counts,
+                    fill_color=colors[idx],
                     line_color=colors[idx],
-                    line_width=3,
+                    **marker_vlines_kwargs,
                 )
+                x_locations = [(bin, bin) for bin in bin_ary]
+                y_locations = [(ymin[idx], counts_) for counts_ in counts]
+                ax.multi_line(x_locations, y_locations, line_color=colors[idx], **vlines_kwargs)
 
             if ref_line:
-                hline = Span(location=all_counts.mean(), line_dash="dashed", line_color="black")
+                hline = Span(location=all_counts.mean(), **ref_line_kwargs)
                 ax.add_layout(hline)
 
         if labels:
diff --git a/arviz/plots/backends/bokeh/violinplot.py b/arviz/plots/backends/bokeh/violinplot.py
index d420791..3ed0aea 100644
--- a/arviz/plots/backends/bokeh/violinplot.py
+++ b/arviz/plots/backends/bokeh/violinplot.py
@@ -58,6 +58,7 @@ def plot_violin(
     else:
         ax = np.atleast_2d(ax)
 
+    current_col = 0
     for (var_name, selection, x), ax_ in zip(
         plotters, (item for item in ax.flatten() if item is not None)
     ):
@@ -89,11 +90,21 @@ def plot_violin(
         )
 
         _title = Title()
+        _title.align = "center"
         _title.text = make_label(var_name, selection)
         ax_.title = _title
         ax_.xaxis.major_tick_line_color = None
         ax_.xaxis.minor_tick_line_color = None
         ax_.xaxis.major_label_text_font_size = "0pt"
+        if current_col != 0:
+            ax_.xaxis.major_label_text_font_size = "0pt"
+            ax_.yaxis.major_label_text_font_size = "0pt"
+            ax_.yaxis.major_tick_line_color = None
+            ax_.yaxis.minor_tick_line_color = None
+            ax_.yaxis.axis_line_color = None
+        current_col += 1
+        if current_col == cols:
+            current_col = 0
 
     show_layout(ax, show)
 
diff --git a/arviz/plots/backends/matplotlib/rankplot.py b/arviz/plots/backends/matplotlib/rankplot.py
index 04db6ed..363f94e 100644
--- a/arviz/plots/backends/matplotlib/rankplot.py
+++ b/arviz/plots/backends/matplotlib/rankplot.py
@@ -20,10 +20,32 @@ def plot_rank(
     colors,
     ref_line,
     labels,
+    ref_line_kwargs,
+    bar_kwargs,
+    vlines_kwargs,
+    marker_vlines_kwargs,
     backend_kwargs,
     show,
 ):
     """Matplotlib rankplot.."""
+    if ref_line_kwargs is None:
+        ref_line_kwargs = {}
+    ref_line_kwargs.setdefault("linestyle", "--")
+    ref_line_kwargs.setdefault("color", "k")
+
+    if bar_kwargs is None:
+        bar_kwargs = {}
+    bar_kwargs.setdefault("align", "center")
+
+    if vlines_kwargs is None:
+        vlines_kwargs = {}
+    vlines_kwargs.setdefault("lw", 2)
+
+    if marker_vlines_kwargs is None:
+        marker_vlines_kwargs = {}
+        marker_vlines_kwargs.setdefault("marker", "o")
+        marker_vlines_kwargs.setdefault("lw", 0)
+
     if backend_kwargs is None:
         backend_kwargs = {}
 
@@ -52,6 +74,8 @@ def plot_rank(
         gap = all_counts.max() * 1.05
         width = bin_ary[1] - bin_ary[0]
 
+        bar_kwargs.setdefault("width", width)
+        bar_kwargs.setdefault("edgecolor", ax.get_facecolor())
         # Center the bins
         bin_ary = (bin_ary[1:] + bin_ary[:-1]) / 2
 
@@ -63,23 +87,22 @@ def plot_rank(
                     bin_ary,
                     counts,
                     bottom=y_ticks[-1],
-                    width=width,
-                    align="center",
                     color=colors[idx],
-                    edgecolor=ax.get_facecolor(),
+                    **bar_kwargs,
                 )
                 if ref_line:
-                    ax.axhline(y=y_ticks[-1] + counts.mean(), linestyle="--", color="k")
+                    ax.axhline(y=y_ticks[-1] + counts.mean(), **ref_line_kwargs)
             if labels:
                 ax.set_ylabel("Chain", fontsize=ax_labelsize)
         elif kind == "vlines":
             ymin = all_counts.mean()
+
             for idx, counts in enumerate(all_counts):
-                ax.plot(bin_ary, counts, "o", color=colors[idx])
-                ax.vlines(bin_ary, ymin, counts, lw=2, colors=colors[idx])
+                ax.plot(bin_ary, counts, color=colors[idx], **marker_vlines_kwargs)
+                ax.vlines(bin_ary, ymin, counts, colors=colors[idx], **vlines_kwargs)
             ax.set_ylim(0, all_counts.mean() * 2)
             if ref_line:
-                ax.axhline(y=all_counts.mean(), linestyle="--", color="k")
+                ax.axhline(y=ymin, **ref_line_kwargs)
 
         if labels:
             ax.set_xlabel("Rank (all chains)", fontsize=ax_labelsize)
diff --git a/arviz/plots/backends/matplotlib/violinplot.py b/arviz/plots/backends/matplotlib/violinplot.py
index 91cc208..2ded74c 100644
--- a/arviz/plots/backends/matplotlib/violinplot.py
+++ b/arviz/plots/backends/matplotlib/violinplot.py
@@ -63,6 +63,7 @@ def plot_violin(
 
     ax = np.atleast_1d(ax)
 
+    current_col = 0
     for (var_name, selection, x), ax_ in zip(plotters, ax.flatten()):
         val = x.flatten()
         if val[0].dtype.kind == "i":
@@ -82,10 +83,16 @@ def plot_violin(
         ax_.plot([0, 0], hdi_probs, lw=linewidth, color="k", solid_capstyle="round")
         ax_.plot(0, per[-1], "wo", ms=linewidth * 1.5)
 
-        ax_.set_xlabel(make_label(var_name, selection), fontsize=ax_labelsize)
+        ax_.set_title(make_label(var_name, selection), fontsize=ax_labelsize)
         ax_.set_xticks([])
         ax_.tick_params(labelsize=xt_labelsize)
         ax_.grid(None, axis="x")
+        if current_col != 0:
+            ax_.spines["left"].set_visible(False)
+            ax_.yaxis.set_ticks_position("none")
+        current_col += 1
+        if current_col == cols:
+            current_col = 0
 
     if backend_show(show):
         plt.show()
diff --git a/arviz/plots/rankplot.py b/arviz/plots/rankplot.py
index 2e1dfe7..aa1ee1f 100644
--- a/arviz/plots/rankplot.py
+++ b/arviz/plots/rankplot.py
@@ -24,6 +24,10 @@ def plot_rank(
     figsize=None,
     ax=None,
     backend=None,
+    ref_line_kwargs=None,
+    bar_kwargs=None,
+    vlines_kwargs=None,
+    marker_vlines_kwargs=None,
     backend_kwargs=None,
     show=None,
 ):
@@ -80,6 +84,18 @@ def plot_rank(
         its own array of plot areas (and return it).
     backend: str, optional
         Select plotting backend {"matplotlib","bokeh"}. Default "matplotlib".
+    ref_line_kwargs : dict, optional
+        Reference line keyword arguments, passed to :meth:`mpl:matplotlib.axes.Axes.axhline` or
+        :meth:`bokeh:bokeh.model.Span`.
+    bar_kwargs : dict, optional
+        Bars keyword arguments, passed to :meth:`mpl:matplotlib.axes.Axes.bar` or
+        :meth:`bokeh:bokeh.plotting.figure.Figure.vbar`.
+    vlines_kwargs : dict, optional
+        Vlines keyword arguments, passed to :meth:`mpl:matplotlib.axes.Axes.vlines` or
+        :meth:`bokeh:bokeh.plotting.figure.Figure.multi_line`.
+    marker_vlines_kwargs : dict, optional
+        Marker for the vlines keyword arguments, passed to :meth:`mpl:matplotlib.axes.Axes.plot` or
+        :meth:`bokeh:bokeh.plotting.figure.Figure.circle`.
     backend_kwargs: bool, optional
         These are kwargs specific to the backend being used. For additional documentation
         check the plotting method of the backend.
@@ -121,6 +137,13 @@ def plot_rank(
         >>> az.plot_rank(centered_data, var_names="mu", kind='vlines', ax=ax[0])
         >>> az.plot_rank(noncentered_data, var_names="mu", kind='vlines', ax=ax[1])
 
+    Change the aesthetics using kwargs
+
+    .. plot::
+        :context: close-figs
+
+        >>> az.plot_rank(noncentered_data, var_names="mu", kind="vlines",
+        >>>              vlines_kwargs={'lw':0}, marker_vlines_kwargs={'lw':3});
     """
     if transform is not None:
         data = transform(data)
@@ -161,6 +184,10 @@ def plot_rank(
         colors=colors,
         ref_line=ref_line,
         labels=labels,
+        ref_line_kwargs=ref_line_kwargs,
+        bar_kwargs=bar_kwargs,
+        vlines_kwargs=vlines_kwargs,
+        marker_vlines_kwargs=marker_vlines_kwargs,
         backend_kwargs=backend_kwargs,
         show=show,
     )
diff --git a/doc/source/conf.py b/doc/source/conf.py
index c37b17e..f2756d6 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -59,6 +59,7 @@ extensions = [
     "IPython.sphinxext.ipython_console_highlighting",
     "gallery_generator",
     "myst_nb",
+    'notfound.extension',
 ]
 
 # ipython directive configuration
@@ -153,6 +154,8 @@ html_static_path = ["_static", thumb_directory]
 html_additional_pages = {
     '404': '404.html',
 }
+# configure notfound extension to not add any prefix to the urls
+notfound_urls_prefix = "/arviz/"
 
 
 # -- Options for HTMLHelp output ------------------------------------------
diff --git a/requirements-docs.txt b/requirements-docs.txt
index e7441cd..674bad6 100644
--- a/requirements-docs.txt
+++ b/requirements-docs.txt
@@ -7,3 +7,4 @@ pydata_sphinx_theme
 selenium
 myst-parser
 myst-nb
+sphinx-notfound-page


Test patch:
diff --git a/arviz/tests/base_tests/test_plots_bokeh.py b/arviz/tests/base_tests/test_plots_bokeh.py
index bba396c..fe5bdbd 100644
--- a/arviz/tests/base_tests/test_plots_bokeh.py
+++ b/arviz/tests/base_tests/test_plots_bokeh.py
@@ -1030,8 +1030,19 @@ def test_plot_posterior_point_estimates(models, point_estimate):
         {"var_names": "mu"},
         {"var_names": ("mu", "tau"), "coords": {"theta_dim_0": [0, 1]}},
         {"var_names": "mu", "ref_line": True},
+        {
+            "var_names": "mu",
+            "ref_line_kwargs": {"line_width": 2, "line_color": "red"},
+            "bar_kwargs": {"width": 50},
+        },
         {"var_names": "mu", "ref_line": False},
         {"var_names": "mu", "kind": "vlines"},
+        {
+            "var_names": "mu",
+            "kind": "vlines",
+            "vlines_kwargs": {"line_width": 0},
+            "marker_vlines_kwargs": {"radius": 20},
+        },
     ],
 )
 def test_plot_rank(models, kwargs):
diff --git a/arviz/tests/base_tests/test_plots_matplotlib.py b/arviz/tests/base_tests/test_plots_matplotlib.py
index 5558d18..4127409 100644
--- a/arviz/tests/base_tests/test_plots_matplotlib.py
+++ b/arviz/tests/base_tests/test_plots_matplotlib.py
@@ -848,8 +848,19 @@ def test_plot_autocorr_var_names(models, var_names):
         {"var_names": "mu"},
         {"var_names": ("mu", "tau"), "coords": {"theta_dim_0": [0, 1]}},
         {"var_names": "mu", "ref_line": True},
+        {
+            "var_names": "mu",
+            "ref_line_kwargs": {"lw": 2, "color": "C2"},
+            "bar_kwargs": {"width": 0.7},
+        },
         {"var_names": "mu", "ref_line": False},
         {"var_names": "mu", "kind": "vlines"},
+        {
+            "var_names": "mu",
+            "kind": "vlines",
+            "vlines_kwargs": {"lw": 0},
+            "marker_vlines_kwargs": {"lw": 3},
+        },
     ],
 )
 def test_plot_rank(models, kwargs):