This might be a simple question but I can't figure it out. In arviz's arviz.plot_forest, how can I swap the order of the shaded backgrounds? For instance, in this example figure from their docs, how can I start with grey and have the odd rows white? Or how do I define and customise this formatting?
Thanks.
Edit after @Onuralp Arslan's answer (6.2.).
The issue I'm facing is that there remains some colour from the original plot, so repainting it to other colours (like red and yellow) works but painting them white for some reason doesn't:
non_centered_data = az.load_arviz_data('non_centered_eight')
centered_data = az.load_arviz_data('centered_eight')
axes = az.plot_forest([non_centered_data, centered_data],
model_names = ["non centered eight", "centered eight"],
kind='forestplot',
var_names=["^the"],
filter_vars="regex",
combined=True,
figsize=(9, 7))
axes[0].set_title('Estimated theta for 8 schools models')
# flip the grey and white
ax=axes[0]
y_ticks = ax.get_yticks()
# to calculate where to color / size of plot
y_min, y_max = ax.get_ylim()
total_height = y_max - y_min
num_rows = len(y_ticks)
row_height = total_height / num_rows
# even odd alternate
for i, y in enumerate(y_ticks):
bottom = y - row_height / 2
top = y + row_height / 2
if i % 2 == 0:
ax.axhspan(bottom, top, color='white', alpha=1, zorder=0)
else:
ax.axhspan(bottom, top, color='lightgrey', alpha=0.2, zorder=-1)
ax.set_axisbelow(True)
produces:
This might be a simple question but I can't figure it out. In arviz's arviz.plot_forest, how can I swap the order of the shaded backgrounds? For instance, in this example figure from their docs, how can I start with grey and have the odd rows white? Or how do I define and customise this formatting?
Thanks.
Edit after @Onuralp Arslan's answer (6.2.).
The issue I'm facing is that there remains some colour from the original plot, so repainting it to other colours (like red and yellow) works but painting them white for some reason doesn't:
non_centered_data = az.load_arviz_data('non_centered_eight')
centered_data = az.load_arviz_data('centered_eight')
axes = az.plot_forest([non_centered_data, centered_data],
model_names = ["non centered eight", "centered eight"],
kind='forestplot',
var_names=["^the"],
filter_vars="regex",
combined=True,
figsize=(9, 7))
axes[0].set_title('Estimated theta for 8 schools models')
# flip the grey and white
ax=axes[0]
y_ticks = ax.get_yticks()
# to calculate where to color / size of plot
y_min, y_max = ax.get_ylim()
total_height = y_max - y_min
num_rows = len(y_ticks)
row_height = total_height / num_rows
# even odd alternate
for i, y in enumerate(y_ticks):
bottom = y - row_height / 2
top = y + row_height / 2
if i % 2 == 0:
ax.axhspan(bottom, top, color='white', alpha=1, zorder=0)
else:
ax.axhspan(bottom, top, color='lightgrey', alpha=0.2, zorder=-1)
ax.set_axisbelow(True)
produces:
Share Improve this question edited Feb 6 at 9:05 My Work asked Feb 5 at 16:27 My WorkMy Work 2,5085 gold badges26 silver badges55 bronze badges 2 |2 Answers
Reset to default 1In arviz docs it says
Returns: 1D ndarray of matplotlib Axes or bokeh_figures
Which we can use this information to manipulate style as a matplotlib suggested in here matplotlib.axes.Axes.axhspan
with ax is the return of arviz.plot_forest
you can use to stylize
y_limits = ax.get_ylim()
num_rows = len(ax.get_yticklabels())
for i in range(num_rows):
if i % 2 == 0: # Even rows (starting from 0)
ax.axhspan(i - 0.5, i + 0.5, color="lightgrey", alpha=0.5) # Grey shading
else: # Odd rows
ax.axhspan(i - 0.5, i + 0.5, color="white", alpha=0.5) # White shading
edit:
You can make any color i have use red and yellow to indicate change just edit color names as you like.
You can expand on this idea with
import arviz as az
import numpy as np
import matplotlib.pyplot as plt
param1 = np.random.randn(100)
param2 = np.random.randn(100)
param3 = np.random.randn(100)
param4 = np.random.randn(100)
param5 = np.random.randn(100)
inference_data = az.from_dict(posterior={
"param1": param1,
"param2": param2,
"param3": param3,
"param4": param4,
"param5": param5
})
fig, ax = plt.subplots()
az.plot_forest(inference_data, ax=ax)
y_ticks = ax.get_yticks()
# to calculate where to color / size of plot
y_min, y_max = ax.get_ylim()
total_height = y_max - y_min
num_rows = len(y_ticks)
row_height = total_height / num_rows
# even odd alternate
for i, y in enumerate(y_ticks):
bottom = y - row_height / 2
top = y + row_height / 2
if i % 2 == 0:
ax.axhspan(bottom, top, color='yellow', alpha=0.2, zorder=0)
else:
ax.axhspan(bottom, top, color='red', alpha=0.2, zorder=0)
ax.set_axisbelow(True)
plt.show()
Which results
Ok, I found a workaround. The issue was that arviz
is producing patch
es for coloured stripes that stay there and no patches for white stripes. So one first has to remove these patches before proceeding with the solution outlined by Onuralp Arslan, thank you for that idea. It is not possible to just repaint the patches as they do not exist for the white background. Note that the repainting can be done in only two lines if one of the colours is white, such as:
if i % 2 != 0:
axes[0].axhspan(bottom, top, color='lightgrey', alpha=0.2, zorder=-1)
The full code is:
non_centered_data = az.load_arviz_data('non_centered_eight')
centered_data = az.load_arviz_data('centered_eight')
axes = az.plot_forest([non_centered_data, centered_data],
model_names = ["non centered eight", "centered eight"],
kind='forestplot',
var_names=["^the"],
filter_vars="regex",
combined=True,
figsize=(9, 7))
axes[0].set_title('Estimated theta for 8 schools models')
# remove the grey background
for ax in axes:
for i, patch in enumerate(ax.patches):
patch.set_facecolor("none")
patch.set_edgecolor("none")
# now repaint the stripes as proposed by Onuralp Arslan
y_ticks = axes[0].get_yticks()
# to calculate where to color / size of plot
y_min, y_max = ax.get_ylim()
total_height = y_max - y_min
num_rows = len(y_ticks)
row_height = total_height / num_rows
# even odd alternate
for i, y in enumerate(y_ticks):
bottom = y - row_height / 2
top = y + row_height / 2
if i % 2 == 0:
axes[0].axhspan(bottom, top, color='white', alpha=1, zorder=0)
else:
axes[0].axhspan(bottom, top, color='lightgrey', alpha=0.2, zorder=-1)
which produces the required:
colors=
parameter ofarviz.plot_forest()
? – JohanC Commented Feb 6 at 22:13