Skip to content

Commit

Permalink
Commitin
Browse files Browse the repository at this point in the history
  • Loading branch information
dafeda committed Aug 22, 2024
1 parent 04d8d61 commit e68df89
Showing 1 changed file with 76 additions and 14 deletions.
90 changes: 76 additions & 14 deletions src/ert/gui/plottery/plots/std_dev.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List
from typing import Any, Dict

import matplotlib.pyplot as plt
import numpy as np
Expand Down Expand Up @@ -28,40 +28,102 @@ def plot(
if layer is not None:
vmin: float = np.inf
vmax: float = -np.inf
axes = []
images: List[npt.NDArray[np.float32]] = []
heatmaps = []
boxplot_axes = []

# Adjusted gridspec to allocate less space to boxplots
gridspec = figure.add_gridspec(2, ensemble_count, height_ratios=[3, 1])

for i, ensemble in enumerate(plot_context.ensembles(), start=1):
ax = figure.add_subplot(1, ensemble_count, i)
axes.append(ax)
# Create two subplots: one for heatmap, one for boxplot
ax_heat = figure.add_subplot(
gridspec[0, i - 1]
) # Heatmap in the upper row
ax_box = figure.add_subplot(
gridspec[1, i - 1]
) # Boxplot in the lower row

data = std_dev_data[ensemble.name]
if data.size == 0:
ax.set_axis_off()
ax.text(
ax_heat.set_axis_off()
ax_box.set_axis_off()
ax_heat.text(
0.5,
0.5,
f"No data for {ensemble.experiment_name} : {ensemble.name}",
ha="center",
va="center",
)
else:
images.append(data)
vmin = min(vmin, float(np.min(data)))
vmax = max(vmax, float(np.max(data)))
ax.set_title(

# Create heatmap with aspect='equal' to make it quadratic
im = ax_heat.imshow(data, cmap="viridis", aspect="equal")
heatmaps.append(im)

# Create boxplot
ax_box.boxplot(data.flatten(), vert=False, widths=0.5)
boxplot_axes.append(ax_box)

# Calculate min, mean, and max
min_value = np.min(data)
mean_value = np.mean(data)
max_value = np.max(data)

# Create a combined annotation in the top-right corner
annotation_text = f"Min: {min_value:.2f}\nMean: {mean_value:.2f}\nMax: {max_value:.2f}"
ax_box.annotate(
annotation_text,
xy=(1, 1), # Top-right corner
xycoords="axes fraction",
ha="right",
va="top",
fontsize=10,
fontweight="bold",
bbox={
"facecolor": "white",
"edgecolor": "black",
"boxstyle": "round,pad=0.3",
},
)

# Remove the frame around the boxplot, except for the bottom spine
ax_box.spines["top"].set_visible(False)
ax_box.spines["right"].set_visible(False)
ax_box.spines["left"].set_visible(False)
ax_box.spines["bottom"].set_visible(True)

# Remove y-axis ticks and labels
ax_box.set_yticks([])
ax_box.set_yticklabels([])

# Only show xlabel for the bottom subplot
ax_heat.set_xlabel("")
ax_box.set_xlabel("Standard Deviation")

# Add colorbar using _colorbar method
self._colorbar(im)

ax_heat.set_title(
f"{ensemble.experiment_name} : {ensemble.name} layer={layer}",
wrap=True,
)

# Apply normalization to all heatmaps after determining global vmin and vmax
norm = plt.Normalize(vmin, vmax)
for ax, data in zip(axes, images):
if data is not None:
im = ax.imshow(data, norm=norm, cmap="viridis")
self._colorbar(im)
for im in heatmaps:
im.set_norm(norm)

# Set x-limits for all boxplots with padding
padding = 0.05 * (vmax - vmin) # 5% padding on each side
for ax_box in boxplot_axes:
ax_box.set_xlim(vmin - padding, vmax + padding)

figure.tight_layout()

@staticmethod
def _colorbar(mappable: Any) -> Any:
# https://joseph-long.com/writing/colorbars/
last_axes = plt.gca()
ax = mappable.axes
assert ax is not None
Expand Down

0 comments on commit e68df89

Please sign in to comment.