I am learning how to use subplots. For example:
import numpy
import matplotlib.pyplot as plt
plt.figure(1)
plt.subplot(221)
plt.subplot(222)
plt.subplot(223)
plt.show()
plt.close(1)
I am getting 3 subplots in figure1
Now I want to make a large subplot with the other subplots within the first one. I tried:
plt.figure(1)
plt.subplot(111)
plt.subplot(222)
plt.subplot(223)
But the first subplot disappears.
My question: is it possible to overlap subplots?
thank you
If you want a total control of the subplots size and position, use Matplotlib add_axes method instead.
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(6, 4))
ax1 = fig.add_axes([0.1, 0.1, 0.85, 0.85])
ax2 = fig.add_axes([0.4, 0.6, 0.45, 0.3])
ax3 = fig.add_axes([0.6, 0.2, 0.2, 0.65])
ax1.text(0.01, 0.95, "ax1", size=12)
ax2.text(0.05, 0.8, "ax2", size=12)
ax3.text(0.05, 0.9, "ax3", size=12)
plt.show()
You can use mpl_toolkits.axes_grid1.inset_locator.inset_axes to create an inset axes on an existing figure.
I added a print statement at the end which shows a list of two axes.
import matplotlib.pyplot as plt
import mpl_toolkits.axes_grid1.inset_locator as mpl_il
plt.plot()
ax2 = mpl_il.inset_axes(plt.gca(), width='60%', height='40%', loc=6)
ax2.plot()
print(plt.gcf().get_axes())
plt.show()
It's not possible to use plt.subplots() to create overlapping subplots. Also, plt.subplot2grid will not work.
However, you can create them using the figure.add_subplot() method.
import matplotlib.pyplot as plt
fig = plt.figure(1)
fig.add_subplot(111)
fig.add_subplot(222)
fig.add_subplot(223)
plt.show()
Related
I'm trying to create some scatter plots, with seaborn with a specific area of each plot highlighted in red. However when I add the code for axvspan, it changes the x-axis. This is how the plots look prior to axvspan being applied.
When i apply the line for axvpsan:
fig, (ax0, ax1) = plt.subplots(2,1, figsize=(5,10))
ax0.axvspan("0.4", "0.8", color='red', alpha=0.3, label ='Problem Area')
sns.scatterplot(x='Values_1', y='Values_2', data=df3, color='green', ax=ax0)
sns.scatterplot(x='Values_3', y='Values_4', data=df3, color='green', ax=ax1)
plt.show()
It sends up looking like this:
Ultimately, the red section needs to only cover the data between 0.4 and 0.7, but by altering the x-axis it ends up covering all of it.
Any advice?
The unexpected behavior is resulting from passing the xmin and xmax arguments to matplotlib.pyplot.axvspan as str and not as float.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
# generate data
rng = np.random.default_rng(12)
df3 = pd.DataFrame({"Values_2": rng.random(100), "Values_1": np.linspace(0., 0.6, 100)})
fig, ax0 = plt.subplots(1,1, figsize=(6, 4))
ax0.axvspan(0.4, 0.8, color='red', alpha=0.3, label ='Problem Area')
sns.scatterplot(x='Values_1', y='Values_2', data=df3, color='green', ax=ax0)
plt.show()
This gives:
I am doing a plot something like this:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)
The last line adds a colorbar and a second axis
fig.axes
>>> [<AxesSubplot:>, <AxesSubplot:label='<colorbar>'>]
My question:
Is there any relation between the two axes that can be used to get the axis of the colorbar (second in the list above) using only the axis returned by ax = plt.gca() (first returned in the list above)?
As far as I know, if you define pcolormesh and colorbar that way, no.
Anyway, you can define an ax for the pcolormesh and a cax for the colorbar beforehand. Then you can pass cax as parameter to matplotlib.pyplot.colorbar. In this way you can access to both axis ax and cax as you need.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
grid_kws = {'width_ratios': (0.9, 0.05), 'wspace': 0.2}
fig, (ax, cax) = plt.subplots(1, 2, gridspec_kw = grid_kws, figsize = (10, 8))
ax.pcolormesh(np.random.rand(10, 10))
plt.colorbar(mpl.cm.ScalarMappable(), cax=cax)
plt.show()
In general, focusing on your code:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)
starting from ax, you can get its figure with ax.figure. From there, you can get the list of all figure axes with ax.figure.axes. So, if you want to get colobar's axis using only pcolormesh' axis, you should use:
ax.figure.axes[1]
The parent figure, as far as I know, is the only relation between the two axes.
I'm using matplotlib to produce a plot where I want to show labels on the right and left y-axis. You will notice by running the code that the grid-lines formed by the right-side y-axis appear on top of the plot line, where the left-side lines appear below. I would like them all to appear below the plot. I've tried zorder and set_axisbelow(True) without success.
Example code below:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
t = np.linspace(0,5)
x = np.exp(-t)*np.sin(2*t)
fig, ax1 = plt.subplots()
ax1.plot(t, x)
ax2 = ax1.twinx()
ax2.plot(t, x, alpha=0.0)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0.1, 0.2])
ax2.set_yticks([0.3, 0.4, 0.5])
ax1.grid(True, color='lightgray')
ax2.grid(True, color='lightgray')
for a in [ax1, ax2]:
a.spines["top"].set_visible(False)
a.spines["right"].set_visible(False)
a.spines["left"].set_visible(False)
a.spines["bottom"].set_visible(False)
ax1.set_axisbelow(True)
ax2.set_axisbelow(True)
plt.savefig('fig.pdf')
plt.show()
I am trying to iterate over multiple plots each with their own labels. The legend values are taken from the list 'iou'. The code below only generates 1 label for iou=0.2. Any help is appreciated.
iou=[0.2, 0.4, 0.6, 0.8]
from matplotlib import pyplot as plt
fig = plt.figure()
for i in range(0,4):
p=plt.plot(recall[i], precision[i], marker='+')
plt.legend(p, iou)
plt.title("PR curves")
plt.xlabel("Recall")
plt.ylabel("Precision")
In each iteration of your loop you'll want to use the label attribute of plt.plot and only after the loop call to plt.legend
from matplotlib import pyplot as plt
iou=[0.2, 0.4, 0.6, 0.8]
fig, ax = plt.subplots(1, 1)
for i in range(0,4):
ax.plot(recall[i], precision[i], marker='+', label=iou[i])
fig.legend()
ax.set_title("PR curves")
ax.set_xlabel("Recall")
ax.set_ylabel("Precision")
A minimal working example could be the following:
from matplotlib import pyplot as plt
import numpy as np
iou=[0.2, 0.4, 0.6, 0.8]
precision = np.random.randint(0, 10, size=(4, 10))
fig, ax = plt.subplots(1, 1)
for i in range(0,4):
ax.plot(np.r_[:10], iou[i] * precision[i], marker='+', label=iou[i])
fig.legend()
ax.set_title("PR curves")
ax.set_xlabel("Recall")
ax.set_ylabel("Precision")
Which gives the following:
I am beginner with python (3.4) and matplotlib. I want to create a wedge with the following code:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig1 = plt.figure()
ax1 = fig1.add_subplot(111, aspect='equal')
ax1.add_patch(patches.Wedge(center=(0,0), r=0.9, theta1=90, theta2=120, facecolor="red", label="Test"))
plt.xlim(-1, 1)
plt.ylim(-1, 1)
fig1.savefig('wedge1.png', dpi=90, bbox_inches='tight')
plt.show()
All Looks fine, but the Label isn't in the plot? Any idea?
You are missing a plt.legend(). You just need to add it anywhere before the plt.show (also before fig1.savefig if you want it saved in the image) and after all your plots:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig1 = plt.figure()
ax1 = fig1.add_subplot(111, aspect='equal')
ax1.add_patch(patches.Wedge(center=(0,0), r=0.9, theta1=90, theta2=120, facecolor="red", label="Test"))
plt.xlim(-1, 1)
plt.ylim(-1, 1)
plt.legend() # <--- here
fig1.savefig('wedge1.png', dpi=90, bbox_inches='tight')
plt.show()
Have a look here for further details on how to use legends.