How to get the AxesImages from matplotlib - matplotlib

all, I use the such code to plot the images
import matplotlib.pyplot as plt
plt.imshow(array,cmap='jet')
plt.show()
however, now I want to get the handle (im) of im=plt.imshow(array,cmap='jet')
How can I get the handle of im if I ignore the handle in the second step.

You can call the method get_images() on the ax.
Example code:
ax = plt.gca()
ax.imshow(array)
ax.get_images() # returns a list of AxesImage objects if any.

You can retrieve all the children present on the axes and filter on the object type.
Like:
ax = plt.gca()
imgs = [obj for obj in ax.get_children() if isinstance(obj, mpl.image.AxesImage)]
If you have only one AxesImage on the axes it returns a list containing one object, for example:
[<matplotlib.image.AxesImage at 0x7be6400>]

Related

Adding Labels to Markers on Relplot

I am a bit lost on the best approach to add labels to my markers with a seaborn relplot. I see in the matplotlib documentation that there is a axes.text() method that looks to be the right approach, but it doesn't appear that this method exists. Does seaborn behave differently than matplotlib in this sense? What would the right approach be?
Error:
AttributeError: 'numpy.ndarray' object has no attribute 'text'
Code:
line_minutes_asleep = sns.relplot(
x = "sleep_date",
y = "minutes_asleep",
kind = "line",
data = df,
height=10, # make the plot 5 units high
aspect=3
)
x = df.sleep_date
y = df.minutes_asleep
names = df.minutes_asleep
print(line_minutes_asleep.axes.text())
relplot returns a FacetGrid, which is a figure containing several subplots. The property .axes of a FacetGrid is a 2D ndarray of Axes objects. Therefore, you need to use FacetGrid.axes[i,j] to get a reference to the subplot.
If you want to write something in the first subplot (axes[0,0]), at the position x,y=(20,5), you would need to do:
import seaborn as sns
sns.set(style="ticks")
tips = sns.load_dataset("tips")
g = sns.relplot(x="total_bill", y="tip", hue="day", data=tips)
g.axes[0,0].text(20,5,"this is a text")

Draw various plots in one figure

The image below shows, what i want, 3 different plots in one execution but using a function
enter image description here
enter image description here
I used the following code:
def box_hist_plot(data):
sns.set()
ax, fig = plt.subplots(1,3, figsize=(20,5))
sns.boxplot(x=data, linewidth=2.5, ax=fig[0])
plt.hist(x=data, bins=50, density=True, ax = fig[1])
sns.violinplot(x = data, ax=fig[2])
and i got this error:
inner() got multiple values for argument 'ax'
Besides the fact that you should not call a Figure object ax and an array of Axes object fig, your problem comes from the line plt.hist(...,ax=...). plt.hist() should not take an ax= parameter, but is meant to act on the "current" axes. If you want to specify which Axes you want to plot, you should use Axes.hist().
def box_hist_plot(data):
sns.set()
fig, axs = plt.subplots(1,3, figsize=(20,5))
sns.boxplot(x=data, linewidth=2.5, ax=axs[0])
axs[1].hist(x=data, bins=50, density=True)
sns.violinplot(x = data, ax=axs[2])

Get data from mplot3d graph

I can’t find out how to get data from an mplot3d graph. Something similar to the 2D style:
line.get_xdata()
Is it possible?
Line3D
You can get get the original data from the (private) _verts3d attribute
xdata, ydata, zdata = line._verts3d
print(xdata)
Complete example
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
mpl.rcParams['legend.fontsize'] = 10
fig = plt.figure()
ax = fig.gca(projection='3d')
# Prepare arrays x, y, z
x = np.arange(5)
y = np.arange(5)*4
z = np.arange(5)*100
line, = ax.plot(x, y, z, label='curve')
fig.canvas.draw()
xdata, ydata, zdata = line._verts3d
print(xdata) # This prints [0 1 2 3 4]
plt.show()
Some explanation: The problem with get_data or get_xdata is that it will return the projected coordinates once the figure is drawn. So while before drawing the figure, line.get_xdata() would indeed return the correct values, after drawing, it would return something like
[ -6.14413090e-02 -3.08824862e-02 -3.33066907e-17 3.12113190e-02 6.27567511e-02]
in the above example, which is the x component of the 3D coordinates projected onto 2D.
There is a pull request to matplotlib, which would allow to get the data via methods get_data_3d. This is still not merged, but might allow the above to be done without using private arguments in a future version of matplotlib.
Poly3DCollection
For a plot_surface plot this looks similar, except that the attribute to look at is the ._vec
surf = ax.plot_surface(X, Y, Z)
xdata, ydata, zdata, _ = surf._vec
print(xdata)
This issue was filed on Github and there is contribution that adds new get_data_3d and set_data_3d methods. Unfortunately, these changes is likely not yet available in distributions. So you might have to continue using private variable line._verts3d.
See more here: https://github.com/matplotlib/matplotlib/issues/8914

Pyplot in iPython: How to continue plotting points inline after exiting a plotting function?

Suppose I had a function plot() that returned a PathCollection instance:
def plot():
fig = pyplot.scatter(1,2)
.... # plot other stuff here
return fig
figure = plot()
This could, in an iPython notebook, be displayed inline (right below the code cell).
I want to call something like
figure.plot(1,2)
to plot a new point (1,2) on that same inline graph, but I can't seem to get this to work. After plotting within a function plot(), how could one continue plotting points on the same plot after exiting plot()?
You even don't need the return value fig:
import matplotlib.pyplot as plt
def plot(x, y):
plt.scatter(x,y)
# plot other stuff here
plot(1, 2)
plot(4, 2)
plot(2, 3)
plot(1, 5)
plt.show()
Then you got:

Why isn't my colorbar appearing in this ImageGrid plot?

I've managed to make a set of subplots using hist2d and ImageGrid with the code below:
from mpl_toolkits.axes_grid1 import ImageGrid
fig = figure(figsize(20, 60))
grid = ImageGrid(fig, 111, nrows_ncols=(1, 3), axes_pad=0.25)
for soa, ax in zip(soalist, grid):
# grab my data from pandas DataFrame...
samps = allsubs[allsubs['soa'] == soa]
x, y = samps['x'], samps['y']
# calls hist2d and returns the Image returned by hist2d
img = gazemap(x, y, ax, std=True, mean=True)
ax.set_title("{0} ms".format(soa * 1000))
# attempt to show a colorbar for that image
grid.cbar_axes[-1].colorbar(img)
show() # threw this in for good measure, but doesn't help!
I get no explicit error (which is good, because I passed an Image to colorbar), but my colorbar does not appear. What gives?
Okay, I fixed it!
All I had to do was pass the cbar_mode and cbar_location kwargs to ImageGrid!