Three plot in one figure using Matplotlib - 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()

Related

Cannot rotate xticks when using two y axes

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()

How to remove offset of axis in matplotlib 3d plot?

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_xlim([0, 1])
plt.show()
results in the following plot:
There is a small margin between the axis and there limits.
How can I get rid of this offset of the axis.
For example ax.set_xlim([0, 1]) has not effect!

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)

How to hide axes in multiple plot

What is wrong for this code for hiding right and top axes, please?
import matplotlib.pyplot as plt
fig, ax = plt.subplots(sharex=True, sharey=True, figsize=(10,3))
fig1 = plt.subplot(121)
fig2 = plt.subplot(122)
# Set width of axes
for figures in [fig1, fig2]:
# Removing axis
for side in ['right','top']:
ax.spines[side].set_visible(False)
plt.show()
This works for non-multiple plot:
for side in ['right','top']:
ax.spines[side].set_visible(False)
EDITED CODE:
import matplotlib.pyplot as plt
import seaborn as sns
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10,3))
fig1 = plt.subplot(121)
ax1.set_xlabel(r'$k$')
ax1.set_ylabel(r'$\omega$', rotation='horizontal')
fig2 = plt.subplot(122)
sns.despine()
plt.show()

Label is Missing from matplotlib legend

I'm plotting subplots with matplotlib and the legend does not show up for some plots.
In this example, the scatter plot legend does not show up.
import numpy as np
import matplotlib
from matplotlib import pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
from matplotlib.patches import Rectangle, Circle
fig = plt.figure()
plt.cla()
plt.clf()
x = np.arange(5) + 1
y = np.full(5, 10)
fig, subplots = plt.subplots(2, sharex=False, sharey=False)
subplots[0].bar(x, y, color='r', alpha=0.5, label='a')
scat = subplots[0].scatter(x, y-1, color='g', label='c')
subplots[0].set_yscale('log')
subplots[1].bar(x, y, color='r', alpha=0.5, label='a')
x = [2, 3]
y = [4, 4]
subplots[1].bar(x, y, color='b', alpha=1, label='b')
subplots[1].set_yscale('log')
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), handler_map={scat: HandlerLine2D(numpoints=4)})
plt.show()
Here is what I tried as a workaround:
p1 = Rectangle((0, 0), 1, 1, fc="r", alpha=0.5)
p2 = Rectangle((0, 0), 1, 1, fc="b")
p3 = Circle((0, 0), 1, fc="g")
legend([p1, p2, p3], ['a', 'b', 'c'], loc='center left', bbox_to_anchor=(1, 0.5))
I really prefer to fix this without the workaround so if anyone knows how to fix it please let me know.
Also, an issue with the workaround is that the Circle object still appears as a bar on the legend.
plt.legend starts with a gca() (which returns the current axes):
# from pyplot.py:
def legend(*args, **kwargs):
ret = gca().legend(*args, **kwargs)
So calling plt.legend will only get you a legend on your last subplot. But it is also possible to call e.g. ax.legend(), or in your case subplots[0].legend(). Adding that to the end of your code gives me a legend for both subplots.
Sample:
for subplot in subplots:
subplot.legend(loc='center left', bbox_to_anchor=(1, 0.5))