Defining a function to make automated plots using matplotlib - python

I am new to python and I need to do a class made of different functions. Each function should be plotting different type of plot with predefined color, size, etc. The user should only call the function and enter two values (x=df or lst, y=df or lst and z the title of the plot) and then get the plot with the format that I have already predefined in the code.
Here is my code:
class Plotter:
def plot_signal(x,y):
plt.figure(figsize=(20, 5) )
plt.plot(x,
y,
color=(142/255.0,186/255.0,229/255.0), alpha=0.1 , linewidth=0.5 );
plt.xlim(left=0)
plt.xlabel('Time [s]', fontsize=11, fontname='Arial')
plt.ylabel('Force [kN]', fontsize=11, fontname='Arial')
plt.xticks(fontsize=8)
plt.yticks(fontsize=8)
plt.savefig(r"filepath\\filename.jpg")
plt.show()
plt.title(z)
return plt.show()
z = "trial"
x = np.random.rand(100)*10
y = np.random.rand(100)
plot_signal(x,y)
and the result (as seen in the photo), is a plot with a different color other than the color I chose, no title, and not even the figure size, it does also save my file, and I do not know how to fix it or what is the problem.
enter image description here

def plot_signal(x, y, z):
plt.figure(figsize=(20, 5))
plt.plot(x, y, color=(142/255.0,186/255.0,229/255.0))
plt.xlabel('Time [s]', fontsize=11, fontname='Arial')
plt.ylabel('Force [kN]', fontsize=11, fontname='Arial')
plt.xticks(fontsize=8)
plt.title(z)
plt.yticks(fontsize=8)
plt.show()
you can change the color by just using color string, the list of the color string can be seen here
example
plt.plot(x, y, color='red')
based on your code, you use alpha=0.1 which means the color will be transparent if it close to 0.
plt.savefig(r"filepath\\filename.jpg")
this line will save your file, you can remove it

Related

How to Animate Text in 3D Scatter Plot?

I would like to animate a 3D scatter plot where each data point has a text label that moves along with it.
Right now the text labels do follow the data points as I want, but they persist through each frame; the text does not disappear from the last animation update. See image below. The data points themselves are moving just fine.
2 Questions whose answers might help me >
Is there some way to clear the text without clearing the data points?
My implementation seems a bit clunky. Is there a hidden function similar to _offset3d that works for text objects.
Here's the graphing function:
def graph(data, update_cnt):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dots = ax.scatter(data[0][0][:], data[1][0][:], data[2][0][:])
dot_txt = nmp.ones(nmp.size(data,2), dtype=str)
for n in range(0,nmp.size(data, 2)):
dot_txt[n] = ax.text(data[0][0][n], data[1][0][n], data[2][0][n],'%s'%(n))
ani = animation.FuncAnimation(fig, update, update_cnt, fargs=(dots, data, dot_txt, ax), interval=300)
plt.show()
and the animation update function:
def update(num, dots, data, dot_txt, ax):
y = data[0][num][:]
x = data[1][num][:]
z = data[2][num][:]
dots._offsets3d = (x, y, z)
#dot_txt._something_to_update_text_here()
dot_txt = nmp.ones(nmp.size(data,2), dtype=str)
for n in range(0,nmp.size(data, 2)):
dot_txt[n] = ax.text(data[1][num][n], data[0][num][n], data[2][num][n],'%s'%(n))
and the current plot output:
I found a solution.
I think it's important to note that I could not use the more common solutions for 3D animated scatter plots because I need different marker styles for various points. This forces me to iteratively plot each scatter point, rather than passing a list to the update function. However in doing so, the problem of animating the text is solved nicely.
frame_list contains the x,y,z coordinates and styling for each data point in every frame.
def graph(frame_list):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
frame_cnt = len(frame_list)
ani = animation.FuncAnimation(fig, update_graph, frame_cnt,
fargs=(frame_list, ax, frame_cnt), interval=600)
plt.show()
The biggest contributor the success of this is the ax.clear() call before every frame.
def update_graph(f, frame_list, ax, cnt):
ax.clear()
f = nmp.mod(f, cnt)
frame = frame_list[f]
for n in range(len(frame.marker)):
x, y, z, s, c, m, name = frame.get_params(n)
ax.scatter(x, y, z, s=s, c=c, marker=m)
ax.text(x, y, z, '%s'%(name))
The get_params function returns all of the relevant data for that frame.

ax.scatter making background figure come to foreground in 3D plot?

I've been working on this complicated plot of trajectories of rockets and maps and things... I came to the point that I needed to include markers on specific places of my map:
Figure without the marker
It's a long code, that requires a lot of data to reproduce, but when I include this line:
ax.scatter(-147.338786 65.32957 85.001453, c='aqua', marker='o', s = 100, label = 'PMC - Water release'
,edgecolors = 'black')
This is the result:
Figure with the marker
I'm using a figure generated with another code to generate the map as a png and add that to the 3D plot like so:
fig = plt.figure(figsize=(16,14))
ax = fig.gca(projection='3d')
ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
k=.01
xx, yy = np.meshgrid(np.linspace(xlims[0],xlims[1],377), np.linspace(ylims[0]+k,ylims[1]+k,317))
# create vertices for a rotated mesh (3D rotation matrix)
X = xx#np.cos(theta)
Y = yy#np.sin(theta)
Z = yy*.0-2.
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=plt.imread(myfolder +
'basemap.png'), shade=False)
basemap.png is the name of the map (sized 377x317).
Does anybody know how to override the figure coming to the foreground with the marker? I don't know why it would do that, but that line (ax.scatter) is the only difference between figure 1 and figure 2.
edit: I did change the order of plot calls and so on, with no positive results

Plotting image Red channel by intensity

Okay, So i'm trying to take the red channel of an image, and plot it (preferably 3d) to an image. The image is 480x640 (or thereabouts), and is taken from a webcam. I'm currently using scipy, numpy, and python to get the image, extract he red channel, and process it. That all works.
However, when i try to plot it, 2 different problems occur, depending on how I try to plot:
1) Width mismatch, it doesn't like that the image isn't square.
2) It only plots one row of the image (x val = 0, all y vals).
I've attached the relevent code. Comments are everywhere, for when i try different ways.
fig = plt.figure()
#ax = Axes3D(fig)
#ax = fig.add_subplot(111, projection='3d')
X = [range(480), range(480)]
Y = [range(480), range(480)]
#X = range(len(self.R))
#Y = range(len(self.R))
'''
surf = ax.plot_surface(X, Y, np.resize(self.R, (480, 480)) , rstride=1, cstride=10, cmap=cm.jet, linewidth=0, antialiased=False)
ax.set_zlim3d(0.0, 255.0)
ax.w_zaxis.set_major_locator(LinearLocator(100))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(self.frame_in)
fig.colorbar(m)
np.savetxt("tmp.txt", self.R)
'''
#np.savetxt("tmp.out", self.R[0])
#np.savetxt("tmp.out1", self.R[1])
#np.savetxt("tmp.txt", self.frame_in, "[ %s ]", "\t")
#plt.subplot(212)
#x, y = self.R.shape
#x = range(x)
#y = range(y)
#X, Y = np.meshgrid(x, y)
plt.scatter(X, Y, self.R)
#plt.pcolormesh(self.R)
#plt.colorbar()
#ax.scatter(x, y, self.R, c='r', marker='o')
plt.show()
I can clean up the code if needed, but i wanted everyone to see the multiple ways i've tried. Am i missing something really stupid simple? It doesn't make sense that it will work with the first row, and not all of them.
Thanks in advance!
Try using pyplot.imshow:
plt.cmap('Reds')
plt.imshow(self.R)
plt.show()

matplotlib rc colorcycle argument with scatterplot

i have configured my own colorcycle in my rc-file (axes.color_cycle) which works fine for the plot command but not for something like:
for i in range(len(x)):
ax.scatter(x[i],y[i],s=area[i], alpha = 0.5)
any ideas how to fix that ?
You dont need to loop in order to use .scatter. You can prepare a list of colors and provide it with color= to scatter. The color method is implemented in such a way that the list of colors does not need to match the length of the data, it gets automatically repeated/cycled or truncated if necessary.
So for example:
fig, ax = plt.subplots()
n = 50
x = np.random.randint(0,100,n)
y = np.random.randint(0,100,n)
area = np.random.randint(20,100,n)
ax.scatter(x, y, s=area, alpha=0.5, color=mpl.rcParams['axes.color_cycle'])
Results in:

Grid Lines below the contour in Matplotlib

I have one question about the grid lines matplotlib.
I am not sure if this is possible to do or not.
I am plotting the following graph as shown in the image.
I won't give the entire code, since it is involving reading of files.
However the important part of code is here -
X, Y = np.meshgrid(smallX, smallY)
Z = np.zeros((len(X),len(X[0])))
plt.contourf(X, Y, Z, levels, cmap=cm.gray_r, zorder = 1)
plt.colorbar()
...
# Set Border width zero
[i.set_linewidth(0) for i in ax.spines.itervalues()]
gridLineWidth=0.1
ax.set_axisbelow(False)
gridlines = ax.get_xgridlines()+ax.get_ygridlines()
#ax.set_axisbelow(True)
plt.setp(gridlines, 'zorder', 5)
ax.yaxis.grid(True, linewidth=gridLineWidth, linestyle='-', color='0.6')
ax.xaxis.grid(False)
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
Now, my questions is like this -
If I put the grid lines below the contour, they disappear since they are below it.
If I put the grid line above the contour, they looks like what they are looking now.
However, what I would like to have is the grid lines should be visible, but should be below the black portion of the contour. I am not sure if that is possible.
Thank You !
In addition to specifying the z-order of the contours and the gridlines, you could also try masking the zero values of your contoured data.
Here's a small example:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
y = np.arange(-2*np.pi, 2*np.pi, 0.1)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) - np.cos(Y)
Z = np.ma.masked_less(Z, 0) # you use mask_equal(yourData, yourMagicValue)
fig, ax = plt.subplots()
ax.contourf(Z, zorder=5, cmap=plt.cm.coolwarm)
ax.xaxis.grid(True, zorder=0)
ax.yaxis.grid(True, zorder=0)
And the output:

Categories

Resources