Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

plt.subplot axis sharing not working

I'm trying to plot some subplots and I can't seem to share axes. I've seen other code and they seem to be doing exactly as I'm attempting but mine doesn't appear to do anything.

I simply want to share the respective axes in the four subplots on the left while keeping the subplot on the far right separate.

import numpy as np
import matplotlib.pyplot as plt

# set the data
x_data = np.linspace(0, 10)
y_data_1 = np.sin(x_data)
y_data_2 = np.cos(x_data)
y_data_3 = [i / 2 for i in y_data_1]
y_data_4 = [j / 2 for j in y_data_2]

# make the plot
ax1 = plt.subplot(2,3,1)
plt.plot(x_data, y_data_1)

ax2 = plt.subplot(2,3,2, sharey=ax1)
plt.plot(x_data, y_data_1)
plt.plot(x_data, y_data_2)

ax3 = plt.subplot(1,3,3)
plt.plot(x_data)

ax4 = plt.subplot(2,3,4, sharex=ax1)
plt.plot(x_data, y_data_1)
plt.plot(x_data, y_data_2)
plt.plot(x_data, y_data_3)

ax5 = plt.subplot(2,3,5, sharex=ax2, sharey=ax4)
plt.plot(x_data, y_data_1)
plt.plot(x_data, y_data_2)
plt.plot(x_data, y_data_3)
plt.plot(x_data, y_data_4)

plt.show()

enter image description here

As you can see, despite adding sharex and sharey arguments into the plt.subplot commands the plot returned shows all unique subplots.

I'm sure I'm making a minor error, but I've tried this in the past and remember that I had the same issue! Any help appreciated, as well as recommendations for alternative approaches. Even the website contains various ways of doing the same thing and it is a little confusing.

like image 846
fffrost Avatar asked Sep 05 '17 21:09

fffrost


2 Answers

You're almost there. You are sharing axes correctly, but need to make the axes invisible (as instructed by the Shared Axis Demo) for some subplots:

plt.setp(ax1.get_xticklabels(), visible=False)

In your code, this might look like:

# make the plot
ax1 = plt.subplot(2, 3, 1)
plt.plot(x_data, y_data_1)
plt.setp(ax1.get_xticklabels(), visible=False)

ax2 = plt.subplot(2, 3, 2, sharey=ax1)
plt.plot(x_data, y_data_1)
plt.plot(x_data, y_data_2)
plt.setp(ax2.get_xticklabels(), visible=False)
plt.setp(ax2.get_yticklabels(), visible=False)

ax3 = plt.subplot(1, 3, 3)
plt.plot(x_data)

ax4 = plt.subplot(2, 3, 4, sharex=ax1)
plt.plot(x_data, y_data_1)
plt.plot(x_data, y_data_2)
plt.plot(x_data, y_data_3)

ax5 = plt.subplot(2, 3, 5, sharex=ax2, sharey=ax4)
plt.plot(x_data, y_data_1)
plt.plot(x_data, y_data_2)
plt.plot(x_data, y_data_3)
plt.plot(x_data, y_data_4)
plt.setp(ax5.get_yticklabels(), visible=False)

plt.show()

That code, plus imports / declared x and y data, results in:

Generated plots

However, there is an even better demo here for creating subplots with shared axes. The best solutions that I saw for shared axes used the .subplots() function to improve the readability / simplicity of the code, e.g.:

f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row')

Best of luck.

like image 159
lcary Avatar answered Oct 01 '22 14:10

lcary


The following would be a solution using plt.subplots. The idea is to turn the rightmost 2 axes of a 2x3 grid invisble and instead create a new subplot at their position.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,10)

fig, ((ax1, ax2, aux1), (ax3, ax4, aux2)) = plt.subplots(2, 3, sharex=True, sharey=True)

#turn rightmost 2 axes off
aux1.axis("off")
aux2.axis("off")

#create a new subplot at their position
ax5 = fig.add_subplot(133)

#plot stuff on the axes
ax1.plot(x,np.sin(x))
ax2.plot(x,np.sin(x))
ax3.plot(x,np.sin(x))
ax4.plot(x,np.sin(x))
ax5.plot(5*x,x)

plt.show()

enter image description here

like image 45
ImportanceOfBeingErnest Avatar answered Oct 01 '22 16:10

ImportanceOfBeingErnest