I'm using matplotlib to plot a probability distribution which looks something like the sum of a Pareto distribution and a Gaussian with positive mean. In other words it has very large values near 0, a small local minimum at x = a, a local maximum at x = b > a, and a long right tail decaying to 0. I'd like to set the y limits based only on those values to the right of the local minimum, i.e. cut off the left-most values so as to focus on the local maximum. I know I can do this with:
plt.plot(pdf)
plt.ylim((0, local_maximum))
However, this sets ymax to exactly the value of the local maximum, which makes the plot look ugly for two reasons:
- the local maximum touches the top boundary of the plot, with no space above
- the y axis is not a round multiple of ytics, so it's not clear what the maximum value is
Matplotlib's algorithm for choosing a default axis is pretty good, so my current hack is to plot twice: the first time I plot only the data above the local minimum for the purpose of choosing a good ylim, and the second time I plot all the data, as follows:
fig, ax = plt.subplots()
# first plot the data above the local minimum x=a, just to get a good ymax
plt.plot(pdf[a:])
ymin, ymax = plt.ylim()
# now plot all the data using the nice ymax
fig.clear()
plt.ylim((0, ymax))
plt.plot(pdf)
This gives me a good ymax that is a round multiple of ytics and fits al the data up to the local maximum, with a bit of whitespace.
Is there a better way, that doesn't require plotting twice?