How to rearrange subplots - python

How can I rearrange my subplots where the plots don't overlap? Appreciate also if there are tips on how to increase the plot sizes :)
Here's my code:
fig = plt.figure()
ax1 = fig.add_subplot(311)
ax1.plot(df[['data1A','data1B','data1C']])
ax1.set_title('group1')
ax2 = fig.add_subplot(312)
ax2.plot(df[['data2A','data2B']])
ax2.set_title('group2')
ax3 = fig.add_subplot(313)
ax3.plot(df['data3A'])
ax3.set_title('group3')

Related

Ticks and Labels on Twin Axes

How can I set the labels on the extra axes?
The ticks and labels should be the same on all 4 axes. I'm doing something wrong... Thanks!
import matplotlib.pyplot as plt
plt.rcParams['text.usetex'] = True
plt.figure(figsize=(5,5))
f, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax3 = ax1.twiny()
plt.show()
# create reusable ticks and labels
ticks = [0,1/2,3.14159/4,3.14159/2,1]
labels = [r"$0$", r"$\displaystyle\frac{1}{2}$", r"$\displaystyle\frac{\pi}{4}$", r"$\displaystyle\frac{\pi}{2}$", r"$1$"]
# Version 1: twinx() + xaxis.set_ticks()
plt.figure(figsize=(5,5))
f, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax3 = ax1.twiny()
ax1.xaxis.set_ticks(ticks, labels=labels)
ax1.yaxis.set_ticks(ticks, labels=labels)
ax2.xaxis.set_ticks(ticks, labels=labels)
ax3.yaxis.set_ticks(ticks, labels=labels)
plt.show()
# Version 2: twinx() + set_xticklabels)()
plt.figure(figsize=(5,5))
f, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax3 = ax1.twiny()
ax1.set_xticks(ticks)
ax1.set_xticklabels(labels)
ax1.set_yticks(ticks)
ax1.set_yticklabels(labels)
ax2.set_xticks(ticks)
ax2.set_xticklabels(labels)
ax3.set_yticks(ticks)
ax3.set_yticklabels(labels)
plt.show()
Confused: How come ax1 has both xaxis and yaxis, while ax2, ax3 do not appear to?
A unintuitive solution based on matplotlib.axes.Axes.twinx:
Create a new Axes with an invisible x-axis and an independent y-axis
positioned opposite to the original one (i.e. at right).
This means unintuitively (at least for me) you have to switch x/y at the .twin call.
unintuitively not concerning the general matplotlib twinx functionality, but concerning such a manual ticks and label assignment
To highlight that a bit more I used ax2_x and ax3_y in the code.
Disclaimer: Not sure if that will break your plot intention when data is added.
Probably at least you have to take special care with the data assignment to those twin axes - keeping that "axis switch" in mind.
Also keep that axis switch" in mind when assigning different ticks and labels to the x/y axis.
But for now I think that's the plot you were looking for:
Code:
import matplotlib.pyplot as plt
plt.rcParams['text.usetex'] = True
# create reusable ticks and labels
ticks = [0,1/2,3.14159/4,3.14159/2,1]
labels = [r"$0$", r"$\displaystyle\frac{1}{2}$", r"$\displaystyle\frac{\pi}{4}$", r"$\displaystyle\frac{\pi}{2}$", r"$1$"]
plt.figure(figsize=(5,5))
f, ax1 = plt.subplots()
ax1.xaxis.set_ticks(ticks, labels=labels)
ax1.yaxis.set_ticks(ticks, labels=labels)
ax2_x = ax1.twiny() # switch
ax3_y = ax1.twinx() # switch
ax2_x.xaxis.set_ticks(ticks, labels=labels)
ax3_y.yaxis.set_ticks(ticks, labels=labels)
plt.show()
Or switch the x/yaxis.set_ticks - with the same effect:
On second thought, I assume that's the preferred way to do it, especially when data comes into play.
ax2_x = ax1.twinx()
ax3_y = ax1.twiny()
ax2_x.yaxis.set_ticks(ticks, labels=labels) # switch
ax3_y.xaxis.set_ticks(ticks, labels=labels) # switch
In case you don't intend to use the twin axis functionality (that means having different data with different scaling assigned to those axis) but 'only' want the ticks and labels on all 4 axis for better plot readability:
Solution based on answer of ImportanceOfBeingErnest with the same plot result:
import matplotlib.pyplot as plt
plt.rcParams['text.usetex'] = True
# create reusable ticks and labels
ticks = [0,1/2,3.14159/4,3.14159/2,1]
labels = [r"$0$", r"$\displaystyle\frac{1}{2}$", r"$\displaystyle\frac{\pi}{4}$", r"$\displaystyle\frac{\pi}{2}$", r"$1$"]
plt.figure(figsize=(5,5))
f, ax1 = plt.subplots()
ax1.xaxis.set_ticks(ticks, labels=labels)
ax1.yaxis.set_ticks(ticks, labels=labels)
ax1.tick_params(axis="x", bottom=True, top=True, labelbottom=True, labeltop=True)
ax1.tick_params(axis="y", left=True, right=True, labelleft=True, labelright=True)
plt.show()
ax2 = ax1.twinx() shares the x-axis with ax1.
ax3 = ax1.twiny() shares the y-axis with ax1.
As a result, the two lines where you set ax2.xaxis and ax3.yaxis's ticks and ticklabels are redundant with the changes you already applied on ax1.
import matplotlib.pyplot as plt
plt.rcParams['text.usetex'] = False # My computer doesn't have LaTeX, don't mind me.
# Create reusable ticks and labels.
ticks = [0, 1/2, 3.14159/4, 3.14159/2, 1]
labels = [r"$0$", r"$\frac{1}{2}$", r"$\frac{\pi}{4}$", r"$\frac{\pi}{2}$", r"$1$"]
# Set the ticks and ticklabels for each axis.
fig = plt.figure(figsize=(5,5))
ax1 = fig.add_subplot()
ax2 = ax1.twinx()
ax3 = ax1.twiny()
for axis in (ax1.xaxis,
ax1.yaxis,
ax2.yaxis,
ax3.xaxis):
axis.set_ticks(ticks)
axis.set_ticklabels(labels)
fig.show()
Notice that if I comment out the work on ax2 and ax3, we get exactly what you have in your question:
for axis in (ax1.xaxis, ax1.yaxis,
# ax2.yaxis,
# ax3.xaxis,
):
axis.set_ticks(ticks)
axis.set_ticklabels(labels)
Now let's ruin ax1 via modifications on ax2, just to show that the bound between twins works well:
ax2.xaxis.set_ticks(range(10))
ax2.xaxis.set_ticklabels(tuple("abcdefghij"))

3D subplots spacing in PyPlot

I want to increase the size of the 3d subplots to occupy most of the empty white space. I am using Gridspec (maybe I'm not using it properly?). I have posted the minimal working example and the output image. You can see the plot is big, but the 3D subplots are smaller with a lot of space between them. How do I increase the size of each subplot to occupy all that empty space?
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(16, 17))
gs = gridspec.GridSpec(6, 4)
ax1 = fig.add_subplot(gs[0:2, 0:2], projection='3d')
ax2 = fig.add_subplot(gs[0:2,2:], projection='3d')
ax3 = fig.add_subplot(gs[2:4,0:2], projection='3d')
ax4 = fig.add_subplot(gs[2:4,2:], projection='3d')
ax5 = fig.add_subplot(gs[4:6,1:3], projection='3d')
axs = [ax1,ax2,ax3,ax4,ax5]
for ax in axs:
ax.set_xlabel('$\psi_2$', fontname='sans serif', fontsize=20)
ax.set_ylabel('$\psi_3$', fontname='sans serif', fontsize=20)
ax.set_zlabel('$\psi_4$', fontname='sans serif', fontsize=20)
ax.view_init(elev=28., azim=81)
plt.tight_layout()
gs.tight_layout(fig)
plt.show()
You can deactivate the tight layout and set each interval to a minimum of 0 horizontally and vertically. Negative values will cause each graph to overlap.
# plt.tight_layout()
# gs.tight_layout(fig)
fig.subplots_adjust(wspace=0, hspace=0)

how to create multiple one plot that contains all my plots

fig = plt.figure()
ax = fig.add_subplot(111)
scatter = ax.scatter(wh1['area'],wh1['rain'],
c=kmeans[0],s=50)
ax.set_title('K-Means Clustering')
ax.set_xlabel('area')
ax.set_ylabel('rain')
plt.colorbar(scatter)
fig = plt.figure()
ax1 = fig.add_subplot(111)
scatter = ax.scatter(wh1['area'],wh1['wind'],
c=kmeans[0],s=50)
ax1.set_title('K-Means Clustering')
ax1.set_xlabel('area')
ax1.set_ylabel('wind')
plt.colorbar(scatter)
plot.show()
this code creates two separate plots, i want to create one plot that contains both of these.i left an image of how the plots appear. Help would be appreciated, thanks
a suggested solution was to avoid plotting twice and using subplots instead, but this causes the 2 graphs to bisect each other any suggested fixes?
fig = plt.figure()
ax = fig.add_subplot(121)
scatter = ax.scatter(wh1['area'],wh1['rain'],
c=kmeans[0],s=50)
ax.set_title('K-Means Clustering')
ax.set_xlabel('area')
ax.set_ylabel('rain')
plt.colorbar(scatter)
ax1 = fig.add_subplot(122)
scatter = ax.scatter(wh1['area'],wh1['wind'],
c=kmeans[0],s=50)
ax1.set_title('K-Means Clustering')
ax1.set_xlabel('area')
ax1.set_ylabel('wind')
plt.colorbar(scatter)
You can use subplots. Instead of making different figures you can call add_subplot on the same figure.
You make a figure by the following code and get a handle to a figure:
fig = plt.figure()
Then you determine the number of rows and columns of plots inside that figure by a number that you pass to the add_subplot function. For example, if you want a layout of one row and two columns the first two digits in the argument is 12 and the third digit determines which cell:
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
So, your code will be like this:
fig = plt.figure()
ax = fig.add_subplot(121)
scatter = ax.scatter(wh1['area'],wh1['rain'],
c=kmeans[0],s=50)
ax.set_title('K-Means Clustering')
ax.set_xlabel('area')
ax.set_ylabel('rain')
plt.colorbar(scatter)
ax1 = fig.add_subplot(122)
scatter = ax1.scatter(wh1['area'],wh1['wind'],
c=kmeans[0],s=50)
ax1.set_title('K-Means Clustering')
ax1.set_xlabel('area')
ax1.set_ylabel('wind')
plt.colorbar(scatter)
plot.show()

Ghost plot being generated

I have the following code:
fig = plt.figure()
ax1 = plt.subplot(211)
ax2 = plt.subplot(212, sharex = ax1)
ax2 = ax1.twinx()
num = list111.lt(-90).sum(1)
plt.yticks(fontsize = 25)
ax = num.plot(figsize=(45,25), ax=ax2, color = 'Red')
df2.plot(y = 'Close', figsize=(45,25), ax=ax1, color = 'Green')
ax1.grid()
ax.margins(x=0)
I am trying to plot ax1 and ax2 in the same graph. What i am getting is a ghost plot:
How can i get rid of the second ghost plot and move the x axis with label to the top plot?
The statement
ax2 = plt.subplot(212, sharex = ax1)
generates a subplot located beneath the ax1 subplot. But it is in contradiction with the statement
ax2 = ax1.twinx()
which points towards a secondary y-axis on the ax1 axes.
If you want all the data to be plotted only on a single axes, you can delete the first statement and use the .twinx() method:
ax1 = plt.axes()
ax2 = ax1.twinx()
# remaining code
otherwise, use both axes separately with
ax1 = plt.subplot(211)
ax2 = plt.subplot(212, sharex = ax1)
# remaining code

How do I create a figure of these two separate polar plots?

I'm attempting to create two separate plots as subplots, on the same figure. Both plots are polar. My attempts cause them to plot on the same graph.
def GenerateTrigonometryTable(x): #Define Function
A = np.arange (0,360,x)
B = np.sin(A*np.pi/180)
C = np.cos(A*np.pi/180)
table = np.dstack(([A],[B],[C]))
return table
Theta = (GenerateTrigonometryTable(5)[:,:,0])
STheta = (GenerateTrigonometryTable(5)[:,:,1])
CTheta = (GenerateTrigonometryTable(5)[:,:,2])
ax1 = plt.subplot(111, projection='polar')
ax1.plot(Theta.flatten(), STheta.flatten())
ax2 = plt.subplot(111, projection='polar')
ax2.plot(Theta.flatten(), CTheta.flatten())
fig.show()
This plots it on the same graph and I need it to be a figure of two separate graphs.
You need the following: 121 means first plot on a 1x2 subplots grid and 122 means second plot on that 1x2 subplots grid.
ax1 = plt.subplot(121, projection='polar')
ax1.plot(Theta.flatten(), STheta.flatten())
ax2 = plt.subplot(122, projection='polar')
ax2.plot(Theta.flatten(), CTheta.flatten())
fig.show()
A more object-oriented approach would be :
fig = plt.figure()
ax1 = fig.add_subplot(121, projection='polar')
ax2 = fig.add_subplot(122, projection='polar')
ax1.plot(Theta.flatten(), STheta.flatten())
ax2.plot(Theta.flatten(), CTheta.flatten())
fig.show()
Equivalent of Sheldore's answer but shows how figures, axes and plots are articulated in matplotlib.

Categories