Cannot rotate xticks when using two y axes - pandas

For some reason, when I create a plot that uses two y-axes I can no longer rotate the xticks using plt.xticks(rotation=45). Are the xticks controlled differently when using two y-axis?
plt.figure()
ax = sns.boxplot(
data=df,
x='x',
y='y',
)
ax2 = ax.twinx()
ax2 = sns.scatterplot(
x='x',
y='y',
ax=ax2,
data=df2,
legend=False,
)
plt.tight_layout()
sns.despine(offset=10, trim=True, bottom=False, right=False)
# seems to have no effect
plt.xticks(rotation=45)
plt.show()

As commented, referencing the first axis solves the issue. The following code does what I was hoping for:
plt.figure()
ax = sns.boxplot(
data=df,
x='x',
y='y',
)
ax2 = ax.twinx()
ax2 = sns.scatterplot(
x='x',
y='y',
ax=ax2,
data=df2,
legend=False,
)
plt.tight_layout()
sns.despine(offset=10, trim=True, bottom=False, right=False)
# now rotates axis labels
ax.set_xticklabels(labels_list, rotation=45)
plt.show()

Related

updating subplots in real time using pyplot

I recently came across a way to refresh a plot with an incoming data stream.
The gist of the script is shown below.
plt.show(block=False) fig = plt.figure()
ax = plt.imshow(data_array, cmap='Greens', interpolation='None',clim=[0, 1], origin='lower', extent=extent, aspect='auto')
for i in range(100):
updating data_array...
ax.set_array(data_array)
fig.canvas.draw()
fig.canvas.flush_events()
This worked very well for a single plot and I wanted to apply this to have two subplots being refreshed in real time.
Below is what I tried.
plt.show(block=False)
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax1 = plt.imshow(data_array_1, cmap='Greens', interpolation='None',clim=[0, 1], origin='lower', extent=extent, aspect='auto')
ax2 = plt.imshow(data_array_2, cmap='Greens', interpolation='None',clim=[0, 1], origin='lower', extent=extent, aspect='auto')
for i in range(100):
updating data_array_1... and data_array_2
ax1.set_array(data_array_1)
ax2.set_array(data_array_2)
fig.canvas.draw()
fig.canvas.flush_events()
Unfortunately, this ended up not working as I hoped.

Seaborn regplot with horizontal subplots with sharey=True and showing y tick labels

I have these three regplots side by side, however, I want to do these:
-increase the size of graphs
-separate them a little bit so can see the y axis more clearly
-see the values on y axis for the two right side graphs.
does anyone know how to do it efficiently? thanks
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, sharey=True)
sns.regplot(x=Dem['Price'], y=Dem['A'], color="g", ax=ax1)
sns.regplot(x=Dem['Price'], y=Dem['B'], color="b", ax=ax2)
sns.regplot(x=Dem['Price'], y=Dem['C'], color="purple", ax=ax3)
You can use: fig.set_figwidth(25) to widen the figure and create space passing whatever numeric value you desire, e.g. 25.
To label the y-axis ticks of all subplots, use:
for ax in fig.axes:
ax.tick_params(axis='y', labelleft=True)
Full reproducible code sample with flights seaborn dataset:
import seaborn as sns
df = sns.load_dataset('flights')
df1 = df[df['year']==1949]
df2 = df[df['year']==1950]
df3 = df[df['year']==1951]
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, sharey=True)
#1
fig.set_figwidth(25)
sns.regplot(x=df1['year'], y=df1['passengers'], color="g", ax=ax1)
sns.regplot(x=df2['year'], y=df2['passengers'], color="b", ax=ax2)
sns.regplot(x=df3['year'], y=df3['passengers'], color="purple", ax=ax3)
#2
for ax in fig.axes:
ax.tick_params(axis='y', labelleft=True)
Your code:
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, sharey=True)
fig.set_figwidth(25)
sns.regplot(x=Dem['Price'], y=Dem['A'], color="g", ax=ax1)
sns.regplot(x=Dem['Price'], y=Dem['B'], color="b", ax=ax2)
sns.regplot(x=Dem['Price'], y=Dem['C'], color="purple", ax=ax3)
for ax in fig.axes:
ax.tick_params(axis='y', labelleft=True)

Three plot in one figure using Matplotlib

I want my plot to look like the image below, how can I achieve that using Matplotlib?
And thanks
You can use GridSpec similar to this tutorial. Possibly there will be not enough space for the y tick labels, which can be mitigated by increasing the default wspace.
import matplotlib.pyplot as plt
fig, axs = plt.subplots(ncols=4, nrows=2, figsize=(12, 7), gridspec_kw={'wspace': 0.4})
gs = axs[0, 0].get_gridspec()
for ax in axs.ravel():
ax.remove()
ax1 = fig.add_subplot(gs[0, :2])
ax1.set_ylabel('A')
ax2 = fig.add_subplot(gs[0, 2:])
ax2.set_ylabel('B')
ax3 = fig.add_subplot(gs[1, 1:3])
ax3.set_ylabel('C')
for ax in (ax1, ax2, ax3):
ax.set_xlabel('D')
ax.legend(handles=[], title='legend', loc='upper right', frameon=False)
plt.show()

Change font size of labels in matplot3D

I have code like:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(xs, ys, zs, c='r', marker='o',label='A')
ax.scatter(x, y, z, c='b', marker='^',label='B')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.tick_params(axis='both', which='major', labelsize=6)
ax.tick_params(axis='both', which='minor', labelsize=6)
plt.savefig(outfile)
The tickparams which works in the 2D version is not working.
How do I do this? The documentation is very hard to read on this.
Note, this is the font size of the titles of the axes, not the tick labels.
The code from the question runs fine.
ax.tick_params(..., labelsize=6)
can be used to change the fontsize of the labels.
The complete example
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x,y,z = zip(*np.random.rand(10,3))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c='b', marker='^',label='B')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.tick_params(axis='both', which='major', labelsize=6)
ax.tick_params(axis='both', which='minor', labelsize=6)
plt.show()
produces this plot:

matplotlib xticks labels overlap

I am not able to get nicer spaces between the xticks with the following code:
import random
import matplotlib.pyplot as plt
coverages = [random.randint(1,10)*2] * 100
contig_names = ['AAB0008r'] * len(coverages)
fig = plt.figure()
fig.clf()
ax = fig.add_subplot(111)
ax.yaxis.grid(True, linestyle='-', which='major', color='grey', alpha=0.5)
ind = range(len(coverages))
rects = ax.bar(ind, coverages, width=0.2, align='center', color='thistle')
ax.set_xticks(ind)
ax.set_xticklabels(contig_names)
#function to auto-rotate the x axis labels
fig.autofmt_xdate()
plt.show()
How to get more space between the xticks so they do not look like overlapped anymore?
Thank you in advance.
You can try changing the figure size, the size of the xticklabels, their angle of rotation, etc.
# Set the figure size
fig = plt.figure(1, [20, 8])
# Set the x-axis limit
ax.set_xlim(-1,100)
# Change of fontsize and angle of xticklabels
plt.setp(ax.get_xticklabels(), fontsize=10, rotation='vertical')