Synchronising dual x axes in a dual (sub)plot in interactive Matplotlib 3.8.1?

  Kiến thức lập trình

Some years ago, I have posted the question Synchronising dual x axes in a dual (sub)plot in interactive Matplotlib? , which ended up having a working solution, which was behaved like this:

Thankfully, the library authors changed the API, so I can spend even more hours debugging the same old issues, and rewriting the same old tired code – providing me with a job for life :)

First, for the line:

ax.get_shared_x_axes().join(ax, ax2, ax22)

… I got the error:

AttributeError: ‘GrouperView’ object has no attribute ‘join’. Did you mean: ‘joined’?

… however, I managed to find AttributeError: ‘GrouperView’ object has no attribute ‘join’ where the accepted error suggests:

ax1.sharey(ax2)
ax2.sharey(ax3)

… but when I try the equivalent with .sharex() in my code, where Matplotlib reports version 3.8.3, I get:

ValueError: x-axis is already shared

Is there a fix to get this working again? Here is my modified code:

#!/usr/bin/env python3

import matplotlib
print("matplotlib.__version__ {}".format(matplotlib.__version__))
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import packaging

#
# Some toy data
x_seq = [x / 100.0 for x in range(1, 100)]
y_seq = [x**2 for x in x_seq]
y2_seq = [0.3*x**2 for x in x_seq]

#
# Scatter plot
fig, (ax, ax2) = plt.subplots(2, 1, sharex=True, figsize=(9, 6), dpi=100, gridspec_kw={'height_ratios': [2, 1]}) # two rows, one column
# Remove horizontal space between axes
fig.subplots_adjust(hspace=0)

ax22 = ax2.twiny() # instantiate a second axes that shares the same y-axis ; /q/31803817

#ax.get_shared_x_axes().join(ax, ax22) # for two axes, from /q/42718823
if packaging.version.Version(matplotlib.__version__) < packaging.version.Version("3.7"):
  ax.get_shared_x_axes().join(ax, ax2, ax22) # in matplotlib 3.8: AttributeError: 'GrouperView' object has no attribute 'join'. Did you mean: 'joined'?
else:
  # from /q/77418896 :
  ax.sharex(ax2)
  ax2.sharex(ax22) # ValueError: x-axis is already shared

# Move twinned axis ticks and label from top to bottom
ax22.xaxis.set_ticks_position("bottom")
ax22.xaxis.set_label_position("bottom")
# Offset the twin axis below the host
ax22.spines["bottom"].set_position(("axes", -0.1))

ax.plot(x_seq, y_seq)
ax2.plot(x_seq, y2_seq)

factor = 655

# FuncFormatter can be used as a decorator
@ticker.FuncFormatter
def major_formatter(x, pos):
  #return "[%.2f]" % x
  return int(factor*x)

ax22.xaxis.set_major_formatter(major_formatter)

#
# Show
plt.show()

Well, sometimes it seems one must post a question, to get to the answer – it seems, all one needs to do is to inverts the “order of sharing” in the second statement:

...
else:
  # from /q/77418896 :
  ax.sharex(ax2)
  ax22.sharex(ax2) # works!
...

… and things seem to work as before; nice!

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT