I am new to Matplotlib. Based on my code in following, I wanted to update the data,title,xlabel,ylabel at same time. However, the title and labels did not been updated, but data did.Someone can give me a solution? That will help me a lot.Thank you.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def updata(frame_number):
current_index = frame_number % 3
a = [[1,2,3],[4,5,6],[7,8,9]]
idata['position'][:,0] = np.asarray(a[current_index])
idata['position'][:,1] = np.asarray(a[current_index])
scat.set_offsets(idata['position'])
ax.set_xlabel('The Intensity of Image1')
ax.set_ylabel('The Intensity of Image2')
ax.set_title("For Dataset %d" % current_index)
fig = plt.figure(figsize=(5,5))
ax = fig.add_axes([0,0,1,1])
idata = np.zeros(3,dtype=[('position',float,2)])
ax.set_title(label='lets begin',fontdict = {'fontsize':12},loc='center')
scat = ax.scatter(idata['position'][:,0],idata['position'][:,1],s=10,alpha=0.3,edgecolors='none')
animation = FuncAnimation(fig,updata,interval=2000)
plt.show()
Running the code, I see an empty window. The reason is that the axes span the complete figure (fig.add_axes([0,0,1,1])). In order to see the title and labels, you would need to make the axes smaller than the figure, e.g. by
ax = fig.add_subplot(111)
Also, the scale of the axes is not defined, so the animation will happen outside the axes limits. You can use ax.set_xlim and ax.set_ylim to prevent that.
Here is a complete running code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def updata(frame_number):
current_index = frame_number % 3
a = [[1,2,3],[4,5,6],[7,8,9]]
idata['position'][:,0] = np.asarray(a[current_index])
idata['position'][:,1] = np.asarray(a[current_index])
scat.set_offsets(idata['position'])
ax.set_xlabel('The Intensity of Image1')
ax.set_ylabel('The Intensity of Image2')
ax.set_title("For Dataset %d" % current_index)
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111)
idata = np.zeros(3,dtype=[('position',float,2)])
ax.set_title(label='lets begin',fontdict = {'fontsize':12},loc='center')
scat = ax.scatter(idata['position'][:,0],idata['position'][:,1],
s=25,alpha=0.9,edgecolors='none')
ax.set_xlim(0,10)
ax.set_ylim(0,10)
animation = FuncAnimation(fig,updata,frames=50,interval=600)
plt.show()
Related
Hi I a have a data set which I project onto a sphere such that the magnitude of the data, as a function of theta and phi, is shown using a colour spectrum (which uses "ax.plot_surface", "plt.colorbar" and "facecolors"). My query is that at this stage I am limited to "cm.hot" and "cm.jet". Does anyone know of any other colour schemes which are available for this purpose. Please see my code and the figures below
Code:
from numpy import*
import math
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.cm as cm
#theta inclination angle
#phi azimuthal angle
n_theta = 100 #number of values for theta
n_phi = 100 #number of values for phi
r = 1 #radius of sphere
theta, phi = np.mgrid[0: pi:n_theta*1j,-pi:pi:n_phi*1j ]
x = r*np.sin(theta)*np.cos(phi)
y = r*np.sin(theta)*np.sin(phi)
z = r*np.cos(theta)
inp = []
f = open("data.dat","r")
for line in f:
i = float(line.split()[0])
j = float(line.split()[1])
val = float(line.split()[2])
inp.append([i, j, val])
inp = np.array(inp)
#reshape the input array to the shape of the x,y,z arrays.
c = inp[:,2].reshape((n_phi,n_theta))
#Set colours and render
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
#use facecolors argument, provide array of same shape as z
# cm.<cmapname>() allows to get rgba color from array.
# array must be normalized between 0 and 1
surf = ax.plot_surface(
x,y,z, rstride=1, cstride=1, facecolors=cm.jet(c), alpha=0.9, linewidth=1, shade=False)
ax.set_xlim([-2.0,2.0])
ax.set_ylim([-2.0,2.0])
ax.set_zlim([-2,2])
ax.set_aspect("equal")
plt.title('Plot with cm.jet')
#Label axis.
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
#Creates array for colorbar from 0 to 1.
a = array( [1.0, 0.5, 0.0])
#Creates colorbar
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(a)
plt.colorbar(m)
plt.savefig('facecolor plots')
f.close()
plt.show()
The following is a list of colormaps provided directly by matplotlib. It's taken from the Colormap reference example.
cmaps = [('Perceptually Uniform Sequential', [
'viridis', 'plasma', 'inferno', 'magma', 'cividis']),
('Sequential', [
'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
('Sequential (2)', [
'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
'hot', 'afmhot', 'gist_heat', 'copper']),
('Diverging', [
'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
('Qualitative', [
'Pastel1', 'Pastel2', 'Paired', 'Accent',
'Dark2', 'Set1', 'Set2', 'Set3',
'tab10', 'tab20', 'tab20b', 'tab20c']),
('Miscellaneous', [
'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg', 'hsv',
'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar'])]
To easily view them all you may e.g. use the following 3D colormap viewer (written in PyQt5).
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from PyQt5 import QtGui, QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.main_widget = QtWidgets.QWidget(self)
self.fig = Figure()
self.canvas = FigureCanvas(self.fig)
self.ax = self.fig.add_subplot(111, projection=Axes3D.name)
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
# Plot the surface
self.surf = self.ax.plot_surface(x, y, z, cmap="YlGnBu")
self.cb = self.fig.colorbar(self.surf)
self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
self.canvas.updateGeometry()
self.dropdown1 = QtWidgets.QComboBox()
items = []
for cats in cmaps:
items.extend(cats[1])
self.dropdown1.addItems(items)
self.dropdown1.currentIndexChanged.connect(self.update)
self.label = QtWidgets.QLabel("A plot:")
self.layout = QtWidgets.QGridLayout(self.main_widget)
self.layout.addWidget(QtWidgets.QLabel("Select Colormap"))
self.layout.addWidget(self.dropdown1)
self.layout.addWidget(self.canvas)
self.setCentralWidget(self.main_widget)
self.show()
self.update()
def update(self):
self.surf.set_cmap(self.dropdown1.currentText())
self.fig.canvas.draw_idle()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = MainWindow()
sys.exit(app.exec_())
I have been looking around and have got to nowhere with this. I am trying to animate the poles on a stereonet diagram. However, the poles do not appear at the location that they should be in.
Figure 1 is the animated pole plot while Figure 2 is how the plot should be. I was wondering if anyone had an idea on how to proceed with this?
import matplotlib as mpl
mpl.use("TkAgg")
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
import mplstereonet
fig, ax = mplstereonet.subplots()
fig2, ax1 = mplstereonet.subplots()
ax.grid(True)
ax1.grid(True)
# Assume a strike and dip with a random variance.
# Current values should plot the poles at either 0, 180
strike, dip = 90, 80
num = 10
strikes = strike + 10 * np.random.randn(num)
dips = dip + 10 * np.random.randn(num)
poles, = ax.pole([], [], 'o')
def init():
poles.set_data([], [])
return poles,
def animate(i):
poles.set_data(strikes[:i], dips[:i])
return poles,
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames = len(strikes), interval = 100, blit=True, repeat=False)
poles1 = ax1.pole(strikes, dips, 'o') # This is how the final image should look like
plt.show()
I would like to add a separate colorbar to each subplot in a 2x2 plot.
fig , ( (ax1,ax2) , (ax3,ax4)) = plt.subplots(2, 2,sharex = True,sharey=True)
z1_plot = ax1.scatter(x,y,c = z1,vmin=0.0,vmax=0.4)
plt.colorbar(z1_plot,cax=ax1)
z2_plot = ax2.scatter(x,y,c = z2,vmin=0.0,vmax=40)
plt.colorbar(z1_plot,cax=ax2)
z3_plot = ax3.scatter(x,y,c = z3,vmin=0.0,vmax=894)
plt.colorbar(z1_plot,cax=ax3)
z4_plot = ax4.scatter(x,y,c = z4,vmin=0.0,vmax=234324)
plt.colorbar(z1_plot,cax=ax4)
plt.show()
I thought that this is how you do it, but the resulting plot is really messed up; it just has an all grey background and ignores the set_xlim , set_ylim commands I have (not shown here for simplicity). + it shows no color bars. Is this the right way to do it?
I also tried getting rid of the "cax = ...", but then the colorbar all goes on the bottom right plot and not to each separate plot!
This can be easily solved with the the utility make_axes_locatable. I provide a minimal example that shows how this works and should be readily adaptable:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
m1 = np.random.rand(3, 3)
m2 = np.arange(0, 3*3, 1).reshape((3, 3))
fig = plt.figure(figsize=(16, 12))
ax1 = fig.add_subplot(121)
im1 = ax1.imshow(m1, interpolation='None')
divider = make_axes_locatable(ax1)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(im1, cax=cax, orientation='vertical')
ax2 = fig.add_subplot(122)
im2 = ax2.imshow(m2, interpolation='None')
divider = make_axes_locatable(ax2)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(im2, cax=cax, orientation='vertical');
In plt.colorbar(z1_plot,cax=ax1), use ax= instead of cax=, i.e. plt.colorbar(z1_plot,ax=ax1)
Specify the ax argument to matplotlib.pyplot.colorbar(), e.g.
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2)
for i in range(2):
for j in range(2):
data = np.array([[i, j], [i+0.5, j+0.5]])
im = ax[i, j].imshow(data)
plt.colorbar(im, ax=ax[i, j])
plt.show()
Please have a look at this matplotlib example page. There it is shown how to get the following plot with four individual colorbars for each subplot:
I hope this helps.
You can further have a look here, where you can find a lot of what you can do with matplotlib.
Try to use the func below to add colorbar:
def add_colorbar(mappable):
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.pyplot as plt
last_axes = plt.gca()
ax = mappable.axes
fig = ax.figure
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cbar = fig.colorbar(mappable, cax=cax)
plt.sca(last_axes)
return cbar
Then you codes need to be modified as:
fig , ( (ax1,ax2) , (ax3,ax4)) = plt.subplots(2, 2,sharex = True,sharey=True)
z1_plot = ax1.scatter(x,y,c = z1,vmin=0.0,vmax=0.4)
add_colorbar(z1_plot)
I have an array with the shape of (#dim1,#dim2,#channel). I want to reshape it to (#channel, #dim1,#dim2).
The plt.reshape(x, (#channel, #dim1,#dim2)) shows me a wrong image.
If you are using the Cifar10 dataset you could use the following code:
import numpy as np
import matplotlib.pyplot as plt
import cPickle
def unpickle(file):
with open(file, 'rb') as fo:
dict = cPickle.load(fo)
return dict
# Read the data
imageDict = unpickle('cifar-10-batches-py/data_batch_2')
imageArray = imageDict['data']
# Now we reshape
imageArray = np.swapaxes(imageArray.reshape(10000,32,32,3,order='F'), 1, 2)
# Get the labels
labels = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']
imageLabels = [labels[i] for i in imageDict['labels']]
# Plot some images
fig, ax = plt.subplots(4,4, figsize=(8,8))
for axIndex in [(i,j) for i in range(4) for j in range(4)]:
index = np.random.randint(0,10000)
ax[axIndex].imshow(imageArray[index], origin='upper')
ax[axIndex].set_title(imageLabels[index])
ax[axIndex].axis('off')
fig.show()
Which gives you:
Using Matplotlib and a for loop, is it possible to display a plot for a given period of time and then have it close when the for loop is done?
I have tried the following, but the plot simply remains open and the loop doesn't end:
import matplotlib.pyplot as plt
import psychopy
x = [34.00,108.00,64.00,99.00,99.00,51.00]
y = [5.00,17.00,11.00,8.00,14.00,5.00]
scatter(x, y, color = "black")
clock = core.Clock()
while clock.getTime() < 10.0:
plt.show()
plt.close()
Thanks
You can use interactive mode plt.ion() in combination with plt.pause().
E.g. to show your window for 5 seconds:
import matplotlib.pyplot as plt
x = [34.00,108.00,64.00,99.00,99.00,51.00]
y = [5.00,17.00,11.00,8.00,14.00,5.00]
plt.scatter(x, y, color = "black")
plt.ion()
plt.draw()
plt.pause(5)