# Plotting posterior predictions from new data - shape mismatch

**URL:** <https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137>\
**Category:** version agnostic\
**Created:** [January 7, 2023, 8:39pm UTC](https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137 "2023-01-07T20:39:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![matsuo\_basho](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@matsuo\_basho](https://discourse.pymc.io/u/matsuo_basho)\
**Post date:** [January 7, 2023, 8:39pm UTC](https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137/1 "2023-01-07T20:39:53Z")

</div>

I’m following [this](https://github.com/pymc-devs/pymc-resources/blob/main/Rethinking_2/Chp_13.ipynb) tutorial that parallel’s McElreath’s Statistical Rethinking.

When I get to cell 43 in the notebook, I get the following error:  
`ValueError: x and y must have same first dimension, but have shapes (4,) and (504,)`

Here’s the full code

```auto
import arviz as az
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pymc as pm

d = pd.read_csv("Data/chimpanzees.csv", sep=";")

treatment = (d.prosoc_left + 2 * d.condition).values
Ntreatments = len(np.unique(treatment))

actor = (d.actor - 1).astype(int).values
Nactor = len(np.unique(actor))

block = (d.block - 1).astype(int).values
Nblock = len(np.unique(block))

with pm.Model() as m_13_4:
    a_bar = pm.Normal("a_bar", 0.0, 1.5)
    sigma_a = pm.Exponential("sigma_a", 1.0)
    sigma_g = pm.Exponential("sigma_g", 1.0)

    a = pm.Normal("a", a_bar, sigma_a, shape=Nactor)
    g = pm.Normal("g", 0.0, sigma_g, shape=Nblock)
    b = pm.Normal("b", 0.0, 0.5, shape=Ntreatments)

    actor_ = pm.Data("actor", actor)
    block_ = pm.Data("block", block)
    treatment_ = pm.Data("treatment", treatment)
    #data = pm.Data("data", d, mutable=True)
    p = pm.Deterministic("p", pm.math.invlogit(a[actor_] + g[block_] + b[treatment_]))
    pulled_left = pm.Binomial("pulled_left", 1, p, observed=d.pulled_left.values)

    trace_13_4 = pm.sample(tune=3000, target_accept=0.99, random_seed=RANDOM_SEED)

chimp = 2
new_data = dict(actor=np.repeat(chimp - 1, 4), block=np.repeat(0, 4), treatment=np.arange(4))

with m_13_4:
    post_pred = pm.sample_posterior_predictive(
        trace_13_4, var_names=["p"], random_seed=RANDOM_SEED
    )["posterior_predictive"]

post_pred["p"].mean(["chain", "draw"]).round(2), az.hdi(post_pred)["p"].round(2)

def chimp_pp_plot(hpd_data, mean_data, title):
    _, ax = plt.subplots(1, 1, figsize=(5, 5))
    az.plot_hdi(range(4), hpd_data)
    ax.plot(range(4), mean_data)

    ax.set_ylim(0, 1.1)
    ax.set_xlabel("treatment")
    ax.set_ylabel("proportion pulled left")
    ax.set_xticks(range(4), ("R/N", "L/N", "R/P", "L/P"))
    plt.title(title)

chimp_pp_plot(
    hpd_data=np.array(post_pred["p"]).T,
    mean_data=post_pred["p"].mean(["chain", "draw"]).round(2),
    title=f"Posterior predictions for chimp #{chimp}",
)

```

I understand that it’s a dimension problem, but not sure how to fix as post\_pred is a dataset type.

---

<div class="post-metadata">

**Author:** ![davipatti](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/davipatti/32/5146_2.png) [@davipatti](https://discourse.pymc.io/u/davipatti)\
**Post date:** [January 10, 2023, 4:15pm UTC](https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137/2 "2023-01-10T16:15:39Z")

</div>

In cell 39 of the ipynb you link to there is a call to `pm.set_data` that your code is missing:

```auto
...

with m_13_4:
    pm.set_data(new_data)

...

```

This line sets values of variables for generating posterior predictions for chimp 2. Without this line, you’re generating posterior predictions for every row in the original data, of which there are 504.

---

<div class="post-metadata">

**Author:** ![matsuo\_basho](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@matsuo\_basho](https://discourse.pymc.io/u/matsuo_basho)\
**Post date:** [January 16, 2023, 12:11am UTC](https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137/3 "2023-01-16T00:11:54Z")

</div>

If I add the pm.set\_data line, then I get the following error:

```auto
TypeError: The variable `actor` must be a `SharedVariable` (created through `pm.MutableData()` or `pm.Data(mutable=True)`) to allow updating. The current type is: <class 'pytensor.tensor.var.TensorConstant'>

```

Not sure what to run pm.Data(mutable=True) on.

---

<div class="post-metadata">

**Author:** ![cluhmann](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/cluhmann/32/3083_2.png) [@cluhmann](https://discourse.pymc.io/u/cluhmann)\
**Post date:** [January 16, 2023, 2:30am UTC](https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137/4 "2023-01-16T02:30:49Z")

</div>

Any data you want to modify needs to either be created with a `pm.Data(..., mutable=False)` statement or, preferably, using `pm.MutableData()`. See [here](https://www.pymc.io/projects/docs/en/latest/api/generated/pymc.Data.html) for details.

---

<div class="post-metadata">

**Author:** ![matsuo\_basho](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@matsuo\_basho](https://discourse.pymc.io/u/matsuo_basho)\
**Post date:** [January 21, 2023, 6:17pm UTC](https://discourse.pymc.io/t/plotting-posterior-predictions-from-new-data-shape-mismatch/11137/5 "2023-01-21T18:17:13Z")

</div>

Initialized all the variables as pm.MutableData and that did the trick:

```auto
with pm.Model() as m_13_4:
    a_bar = pm.Normal("a_bar", 0.0, 1.5)
    sigma_a = pm.Exponential("sigma_a", 1.0)
    sigma_g = pm.Exponential("sigma_g", 1.0)

    a = pm.Normal("a", a_bar, sigma_a, shape=Nactor)
    g = pm.Normal("g", 0.0, sigma_g, shape=Nblock)
    b = pm.Normal("b", 0.0, 0.5, shape=Ntreatments)

    actor_ = pm.MutableData("actor", actor)
    block_ = pm.MutableData("block", block)
    treatment_ = pm.MutableData("treatment", treatment)
    data = pm.MutableData("data", d)
    p = pm.Deterministic("p", pm.math.invlogit(a[actor_] + g[block_] + b[treatment_]))
    pulled_left = pm.Binomial("pulled_left", 1, p, observed=d.pulled_left.values)

    trace_13_4 = pm.sample(tune=3000, target_accept=0.99, random_seed=RANDOM_SEED)

```

Are there any drawbacks to using MutableData? Seems like unless you know you won’t absolutely be using to predict on new data, no reason not to use it when specifying a model.
