PyMC3 traceplot not displaying - python

I am trying to get the PyMC3 examples from Osvaldo Martin's Bayesian Analysis with Python working. On Windows 10, while the following code using matplotlib works fine (i.e. a chart is displayed):
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
def posterior_grid(grid_points=100, heads=6, tosses=9):
"""
A grid implementation for the coin-flip problem
"""
grid = np.linspace(0, 1, grid_points)
prior = 0.5 - abs(grid - 0.5)
likelihood = stats.binom.pmf(heads, tosses, grid)
unstd_posterior = likelihood * prior
posterior = unstd_posterior / unstd_posterior.sum()
return grid, posterior
if __name__ == "__main__":
points = 100
h, n = 1, 4
grid, posterior = posterior_grid(points, h, n)
plt.plot(grid, posterior, 'o-', label='heads = {}\ntosses = {}'.format(h, n))
plt.xlabel(r'$\theta$')
plt.legend(loc=0)
plt.show()
...I cannot get the following - which uses PyMC3's traceplot - to display a chart:
import pymc3 as pm
import numpy as np
import scipy.stats as stats
if __name__ == "__main__":
np.random.seed(123)
n_experiments = 4
theta_real = 0.35
data = stats.bernoulli.rvs(p=theta_real, size=n_experiments)
print(data)
with pm.Model() as our_first_model:
theta = pm.Beta('theta', alpha=1, beta=1)
y = pm.Bernoulli('y', p=theta, observed=data)
start = pm.find_MAP()
step = pm.Metropolis()
trace = pm.sample(1000, step=step, start=start)
burnin = 100
chain = trace[burnin:]
pm.traceplot(chain, lines={'theta':theta_real});
The code runs and exits fine, but no chart is displayed.
I have tried in IntelliJ IDEA with the Python plugin, from an Anaconda console window for my root environment, and from IPython.
In IPython, I get the following output on the console:
Out[3]:
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000024BDD622F60>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000024BDD667208>]], dtype=object)
...so obviously something is happening. But how can I display the results as a chart?
I have also tried the exact library versions listed in the book with Python 3.5, but still no traceplot chart:
Ipython 5.0
NumPy 1.11.1
SciPy 0.18.1
Pandas 0.18.1
Matplotlib 1.5.3
Seaborn 0.7.1
PyMC3 3.0

Various further Googling got me to the following answers.
With IPython, you must invoke with ipython --pylab auto to give matplotlib a suitable backend (on Windows at least).
With IntelliJ IDEA / PyCharm, you need to add
import matplotlib.pyplot as plt
and then
plt.show()
after the traceplot line to show the plot.

Related

Interactive plot with ipyvidgets and matplotlib on binder produces static images

I'm trying to share a github repo on binder. Locally, my interactive plot using matplotlib and #interact works ok. On binder it works half way. Same code adds static images to the cell output in binder notebook when slider value changes.
Question: how to fix binder behavior and make an interactive plot?
git repository https://github.com/queezz/Complex_Numbers
My notebook looks like this:
%pylab inline
from ipywidgets import interact, widgets
x = np.linspace(0,np.pi,100)
#interact
def plot_interactive(a=widgets.FloatSlider(min=1, max=10, val=1)):
plot(x,np.sin(x*a))
gca().set_aspect('equal')
ylim(-1.1,1.1)
Screenshot from binder:
Found a good working example:
https://github.com/Kapernikov/ipywidgets-tutorial
The gist of it is to use %matplotlib widget and #widgets.interact.
It seems that usage of %pylab inline is discouraged now, see this git issue.
I copy a part of the code from the tutorial which produces the same result as wanted in the question.
%matplotlib widget
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
# set up plot
fig, ax = plt.subplots(figsize=(6, 4))
ax.set_ylim([-4, 4])
ax.grid(True)
# generate x values
x = np.linspace(0, 2 * np.pi, 300)
def my_sine(x, w, amp, phi):
"""
Return a sine for x with angular frequeny w and amplitude amp.
"""
return amp*np.sin(w * (x-phi))
#widgets.interact(w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))
def update(w = 1.0, amp=1, phi=0):
"""Remove old lines from plot and plot new one"""
[l.remove() for l in ax.lines]
ax.plot(x, my_sine(x, w, amp, phi), color='C0')
I wasn't able to get #queez's answer that uses 'interact' to work today (later updated in early 2023 is below); however, the ipywidgets documentation presently includes a matplotlib example, which uses 'interactive', that I was able to take and adapt #qqueezz's solution to get it working. This seems to be a much more streamlined route to make an interactive plot.
#%matplotlib inline # from the example in the documentation. but doesn't seem necessary in current JupyterLab 3.1.11 or the classic notebook available now https://github.com/fomightez/communication_voila
from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np
def my_sine(x, w, amp, phi):
"""
Return a sine for x with angular frequency w and amplitude amp.
"""
return amp*np.sin(w * (x-phi))
def f( w, amp, phi):
plt.figure(2)
x = np.linspace(0, 2 * np.pi, 300)
plt.plot(x, my_sine(x, w, amp, phi), color='C0')
#plt.ylim(-5, 5)
plt.grid(True) #optional grid
plt.show()
interactive_plot = interactive(f, w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))
#output = interactive_plot.children[-1]
#output.layout.height = '450px'
interactive_plot
You can go to the repo here, launch a session by choosing the launch binder badge to the right of 'Start with the matplotlib & widget demo as a notebook' under 'Direct links to start out in notebook mode:'.
Or click here to launch directly into that notebook via MyBinder.
UPDATE:
Later (early 2023), I found queez's code from Kapernikov: Ipywidgets with matplotlib did work with interact in JupyterLab using ipympl.
Not following yet what changed; however, wanted to note.

ArviZ plot_trace does not properly plot multidimensional variables

I'm attempting to run a basic test model using PyMC3, but I've found the ArviZ plot_trace function won't properly show my traces.
Code
from scipy import stats
import arviz as az
import numpy as np
import matplotlib.pyplot as plt
import pymc3 as pm
import seaborn as sns
import pandas as pd
from theano import shared
from sklearn import preprocessing
if __name__ == "__main__":
with basic_model:
# Priors for unknown model parameters
alpha = pm.Normal('alpha', mu=0, sigma=10)
beta = pm.Normal('beta', mu=0, sigma=10, shape=2)
sigma = pm.HalfNormal('sigma', sigma=1)
# Expected value of outcome
mu = alpha + beta[0]*X1 + beta[1]*X2
# Likelihood (sampling distribution) of observations
Y_obs = pm.Normal('Y_obs', mu=mu, sigma=sigma, observed=Y)
# draw 500 posterior samples
trace = pm.sample(5000)
az.plot_trace(trace, compact = False)
The beta parameter is multidimensional, and has both beta[0] and beta[1], but the ArviZ trace only shows beta[0]:
Trace Plot
If I run the trace plot as az.plot_trace(trace, compact = True), then I do see both dimensions of beta properly overlaid. I only observed this issue when trying to plot the dimensions in separate axes with compact = False.
Versions
ArviZ: 0.6.1
Numpy: 1.18.1
SciPy: 1.4.1
xarray: 0.15.0
Matplotlib: 3.1.3
It looks like you are running into this bug. I'd recommend updating ArviZ to its latest version (0.7.0 at the time of writing) which already includes a fix for this particular bug.
If you had some kind of version constraint, then disabling numba should fix the issue.

How to pull samples with a tweedie distribution using numpy

I'm trying to plot a CDF of random samples to compare to a target within a dataset that follows a tweedie distribution. I know the following code will pull random samples along a poisson distribution:
import numpy as np
import matplotlib.pyplot as plt
x_r = np.random.poisson(lam = coll_df['pure_premium'].mean(), size = len(coll_df['pure_premium'])).sort()
y_r = np.arange(1, len(x)+1)/len(x)
_ = plt.plot(x, y_r, color = 'red')
_ = plt.xlabel('Percent of Pure Premium')
_ = plt.ylabel('ECDF')
However, there is no tweedie distribution option on the random sampling. Anyone know how to hack this together?
PyPI has a tweedie package. A minimal example drawing a sample would be:
import tweedie, seaborn as sns, matplotlib.pyplot as plt
tvs = tweedie.tweedie(mu=10, p=1.5, phi=20).rvs(100000)
sns.distplot(tvs)
plt.show()
The package's GitHub pages have a more fancy example. The package implements rv_continuous, so one gets a bunch of other functionality besides rvs(). Also, while there seems no nice online docs, help(tweedie.tweedie) gives lots of detail.

plots don't work in matplotlib

I am unable to display images in iPython from matplotlib, an image appears for a split of a second in a pop up window instead of inline and then closes immediately. nothing appears in the iPython console which is inside Spyder.
from statistics import mean
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import style
style.use('fivethirtyeight')
xs = np.array([1,2,3,4,5,6], dtype=np.float64)
ys = np.array([5,4,6,5,6,7], dtype=np.float64)
def best_fit_slop_and_intercept (xs,ys):
m = ( ((mean(xs)*mean(ys))-mean(xs*ys)) /
((mean(xs)**2)-mean(xs**2)) )
b = mean(ys)-m*mean(xs)
return m,b
m,b = best_fit_slop_and_intercept(xs,ys)
print (m,b)
regression_line = [m*x + b for x in xs ]
print (regression_line)
predict_x = 9
predict_y = predict_x*m + b
plt.scatter(predict_x,predict_y, color = 'g')
plt.scatter(xs,ys)
plt.plot(xs, regression_line)
plt.show()
You can type %matplotlib inline inside the iPython console to generate your plots within the console inside spyder. You can also type %matplotlib qtto get an interactive window.
Your code snippet works for me with both settings. Failing that you can go to [preferences>iPython console>Graphics>Graphics backend] to adjust the graphics defaults and settings to see if that fixes the problem.

How to display a graph in ipython notebook

Trying to do some plotting in SymPy -
As per this video I have written :
from sympy.plotting import plot, plot_parametric
e = sin(2*sin(x**3))
plot(e, (x, 0, 5));
But after evaling that cell I don't get any output? There isn't an error or
anything, it just doesn't display anything.
Another test :
from sympy import *
from sympy.plotting import plot, plot_parametric
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
expr = x**2 + sqrt(3)*x - Rational(1, 3)
lf = lambdify(x, expr)
fig = plt.figure()
axes = fig.add_subplot(111)
x_vals = np.linspace(-5., 5.)
y_vals = lf(x_vals)
axes.grid()
axes.plot(x_vals, y_vals)
plt.show();
So Im not sure what I'm doing wrong here, I'm not getting any errors though?
If the virtual environment content is of any interest here's a tree of that :
venv
I'm running this on Linux Ubuntu. The virtual environment that it's running in can be seen in the above paste link
You need to use the magic functions, more specifically the ones for matplotlib:
%matplotlib qt # displays a pop-up of the plot
%matplotlib inline # keeps it within the notebook
Runnable example using Python 3.4 Nov '15:
from sympy import *
from sympy.plotting import plot, plot_parametric
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
expr = x**2 + sqrt(3)*x - Rational(1, 3)
lf = lambdify(x, expr)
fig = plt.figure()
axes = fig.add_subplot(111)
x_vals = np.linspace(-5., 5.)
y_vals = lf(x_vals)
axes.grid()
axes.plot(x_vals, y_vals)
To get plots to show inline in the IPython notebook, you need to enable matplotlib's inline backend. You can do this by running
%matplotlib inline

Categories

Resources