I need two overlay two datasets with different Y-axis scales in Matplotlib. The data contains both positive and negative values. I want the two axes to share one origin, but Matplotlib does not align the two scales by default.
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax1.bar(range(6), (2, -2, 1, 0, 0, 0))
ax2.plot(range(6), (0, 2, 8, -2, 0, 0))
plt.show()
I suppose it is possible to perform some computation with .get_ylim()
and .set_ylim()
two align the two scales. Is there an easier solution?
use the align_yaxis() function:
In order to ensure that the y-bounds are maintained (so no data points are shifted off the plot), and to balance adjustment of both y-axes, I made some additions to @HYRY's answer:
I've cooked up a solution starting from the above that will align any number of axes:
example:
@drevicko's answer fails for me when plotting the following two sequences of points:
... so here's my version:
There are in principle infinite different possibilities to align the zeros (or other values, which the other provided solutions accept): wherever you place zero on the y axis, you can zoom each of the two series so that it fits. We just pick the position such that, after the transformation, the two cover a vertical interval of same height. Or in other terms, we minimize them of a same factor compared to the non-aligned plot. (This does not mean that 0 is at half of the plot: this will happen e.g. if one plot is all negative and the other all positive.)
Numpy version: