plotting wrong on x axis - numpy

thank you for reading my question
I have to plot my data like that. When I plot my data
I am having an output like this.
Code for reading the data from the file and plotting is below
#!/usr/bin/env python3.8
import matplotlib.pyplot as plt
import numpy as np
with open('data.txt','r') as file2:
y= [line.rstrip('\n') for line in file2]
notf2=y[2:]
z=[a.rstrip(' ') for a in notf2]
x_data=[]
y_data=[]
for j in range(0, len(z)):
x_data += [z[j][:3]]
y_data += [z[j][5:]]
x__data=[]
y__data=[]
for k in range(0, len(z)):
x__data += [x_data[k]]
y__data += [y_data[k]]
rx=x__data.reverse()
ry=y__data.reverse()
#plt.plot(x__data[::-1],y__data, '.')
plt.plot(x__data,y__data, '.')
plt.show()
I don't understand why it is plotting it different. It is reversing x axis
but when I try to reverse it
plt.plot(x__data[::-1],y__data, '.')
it is not fixing it , just showing the same thing. When I plot
plt.plot(x__data[::-1],y__data, '.')
plt.plot(x__data,y__data, '.')
both of those it is reversing and showing . And I am not even talking about those numbers (black lines) written as if they are labels

Your data are strings. You need to convert them to float

Related

In matplotlib, is there a method to fix or arrange the order of x-values of a mixed type with a character and digits?

There are several Q/A for x-values in matplotlib and it shows when the x values are int or float, matploblit plots the figure in the right order of x. For example, in character type, the plot shows x values in the order of
1 15 17 2 21 7 etc
but when it became int, it becomes
1 2 7 15 17 21 etc
in human order.
If the x values are mixed with character and digits such as
NN8 NN10 NN15 NN20 NN22 etc
the plot will show in the order of
NN10 NN15 NN20 NN22 NN8 etc
Is there a way to fix the order of x values in the human order or the existing order in the x list without removing 'NN' in x-values.
In more detail, the xvalues are directory names and using grep sort inside linux function, the results are displayed in linux terminal as follows, which can be saved in text file.
joonho#login:~/NDataNpowN$ get_TEFrmse NN 2 | sort -n -t N -k 3
NN7 0.3311
NN8 0.3221
NN9 0.2457
NN10 0.2462
NN12 0.2607
NN14 0.2635
Without sort, the linux shell also displays in the machine order such as
NN10 0.2462
NN12 0.2607
NN14 0.2635
NN7 0.3311
NN8 0.3221
NN9 0.2457
As I said, pandas would make this task easier than dealing with base Python lists and such:
import matplotlib.pyplot as plt
import pandas as pd
#imports the text file assuming that your data are separated by space, as in your example above
df = pd.read_csv("test.txt", delim_whitespace=True, names=["X", "Y"])
#extracting the number in a separate column, assuming you do not have terms like NN1B3X5
df["N"] = df.X.str.replace(r"\D", "", regex=True).astype(int)
#this step is only necessary, if your file is not pre-sorted by Linux
df = df.sort_values(by="N")
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 6))
#categorical plotting
df.plot(x="X", y="Y", ax=ax1)
ax1.set_title("Evenly spaced")
#numerical plotting
df.plot(x="N", y="Y", ax=ax2)
ax2.set_xticks(df.N)
ax2.set_xticklabels(df.X)
ax2.set_title("Numerical spacing")
plt.show()
Sample output:
Since you asked if there is a non-pandas solution - of course. Pandas makes some things just more convenient. In this case, I would revert to numpy. Numpy is a matplotlib dependency, so in contrast to pandas, it must be installed, if you use matplotlib:
import matplotlib.pyplot as plt
import numpy as np
import re
#read file as strings
arr = np.genfromtxt("test.txt", dtype="U15")
#remove trailing strings
Xnums = np.asarray([re.sub(r"\D", "", i) for i in arr[:, 0]], dtype=int)
#sort array
arr = arr[np.argsort(Xnums)]
#extract x-values as strings...
Xstr = arr[:, 0]
#...and y-values as float
Yvals = arr[:, 1].astype(float)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 6))
#categorical plotting
ax1.plot(Xstr, Yvals)
ax1.set_title("Evenly spaced")
#numerical plotting
ax2.plot(np.sort(Xnums), Yvals)
ax2.set_xticks(np.sort(Xnums))
ax2.set_xticklabels(Xstr)
ax2.set_title("Numerical spacing")
plt.show()
Sample output:

Matplotlib line plot of Numpy array change color at specified percentage

Say you have a numpy array containing about 2000 elements of decimals ranging between 0 to 5. Using matplotlib, how would you line plot the first 75% of these decimals in this numpy array in blue and the remaining 25% elements in red?
The following code first creates some toy data with 2000 values between 0 and 5. The first 3/4th is plotted in blue, the rest in red.
import numpy as np
import matplotlib.pyplot as plt
data = np.random.uniform(0, 5, 2000)
threefourth = len(data) * 3 // 4
plt.plot(range(threefourth+1), data[:threefourth + 1], color='dodgerblue')
plt.plot(range(threefourth, len(data)), data[threefourth:], color='crimson')
plt.show()
You might get away, depending on your data, by plotting first a blue line with all the data, and than plot a red line with the data of the lower decimals masked by replacing them with nan's with np.where. See the following example. (Line segments that cross the red/blue border are problematic and will be plotted blue in this case.)
For a better control have a look at the Multicolored lines example from the matplotlib documentation.
import numpy as np
import matplotlib.pyplot as plt
xs = np.arange(0,2000)
ys = ( 2.4
+ 2.0 * np.sin(3 * 2 * np.pi * xs / 2000)
+ 0.3 * np.random.random(size=2000)
)
red_ys = np.where( ys < 0.75 * 5 , np.nan , ys )
plt.plot(ys, 'b')
plt.plot(red_ys, 'r')
plt.show()

Multiple different kinds of plots on a single figure and save it to a video

I am trying to plot multiple different plots on a single matplotlib figure with in a for loop. At the moment it is all good in matlab as shown in the picture below and then am able to save the figure as a video frame. Here is a link of a sample video generated in matlab for 10 frames
In python, tried it as below
import matplotlib.pyplot as plt
for frame in range(FrameStart,FrameEnd):#loop1
# data generation code within a for loop for n frames from source video
array1 = np.zeros((200, 3800))
array2 = np.zeros((19,2))
array3 = np.zeros((60,60))
for i in range(len(array2)):#loop2
#generate data for arrays 1 to 3 from the frame data
#end loop2
plt.subplot(6,1,1)
plt.imshow(DataArray,cmap='gray')
plt.subplot(6, 1, 2)
plt.bar(data2D[:,0], data2D[:,1])
plt.subplot(2, 2, 3)
plt.contourf(mapData)
# for fourth plot, use array2[3] and array2[5], plot it as shown and keep the\is #plot without erasing for next frame
not sure how to do the 4th axes with line plots. This needs to be there (done using hold on for this axis in matlab) for the entire sequence of frames processing in the for loop while the other 3 axes needs to be erased and updated with new data for each frame in the movie. The contour plot needs to be square all the time with color bar on the side. At the end of each frame processing, once all the axes are updated, it needs to be saved as a frame of a movie. Again this is easily done in matlab, but not sure in python.
Any suggestions
thanks
I guess you need something like this format.
I have used comments # in code to answer your queries. Please check the snippet
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(6,6))
ax1=fig.add_subplot(311) #3rows 1 column 1st plot
ax2=fig.add_subplot(312) #3rows 1 column 2nd plot
ax3=fig.add_subplot(325) #3rows 2 column 5th plot
ax4=fig.add_subplot(326) #3rows 2 column 6th plot
plt.show()
To turn off ticks you can use plt.axis('off'). I dont know how to interpolate your format so left it blank . You can adjust your figsize based on your requirements.
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(6,6)) #First is width Second is height
ax1=fig.add_subplot(311)
ax2=fig.add_subplot(312)
ax3=fig.add_subplot(325)
ax4=fig.add_subplot(326)
#Bar Plot
langs = ['C', 'C++', 'Java', 'Python', 'PHP']
students = [23,17,35,29,12]
ax2.bar(langs,students)
#Contour Plot
xlist = np.linspace(-3.0, 3.0, 100)
ylist = np.linspace(-3.0, 3.0, 100)
X, Y = np.meshgrid(xlist, ylist)
Z = np.sqrt(X**2 + Y**2)
cp = ax3.contourf(X, Y, Z)
fig.colorbar(cp,ax=ax3) #Add a colorbar to a plot
#Multiple line plot
x = np.linspace(-1, 1, 50)
y1 = 2*x + 1
y2 = 2**x + 1
ax4.plot(x, y2)
ax4.plot(x, y1, color='red',linewidth=1.0)
plt.tight_layout() #Make sures plots dont overlap
plt.show()

How do I fit a line to this data?

I've got the following data:
I'm interested in fitting a line on the 'middle bit' (intercept 0). How do I do that? It would be useful to get a figure for the gradient as well.
(FYI These are a list of cash transactions, in and out. The gradient would be the profit or loss).
Here's some of the data:
https://gist.github.com/chrism2671/1081c13b6760878b457a112d2041622f
You can use numpy.polyfit and numpy.poly1d to achieve that:
import matplotlib.pyplot as plt
import numpy as np
# Create data
ls = np.linspace(0, 100)
s = np.random.rand(len(ls))*100 + ls
# Fit the data
z = np.polyfit(ls, s, deg=1)
p = np.poly1d(z)
# Plotting
plt.figure(figsize=(16,4.5))
plt.plot(ls, s,
alpha=.75, label='signal')
plt.plot(ls, p(ls),
linewidth=1, linestyle='--', color='r', label='polyfit')
plt.legend(ncol=2)
Using the data you provided:

matplotlib doesn't show lines

I have a data file exported from octave which include two vectors x and u0 . I want to plot u0 versus x in matplotlib with the following codes
import scipy.io
import matplotlib.pyplot as plt
data = scipy.io.loadmat('myfile.mat')
x = data['x']
u0 = data['u0']
plt.plot(x,u0)
plt.show()
The above codes gives just a blank figure
When I changed the line plt.plot(x,u0) with plt.plot(x,u0,'-bo') I got the following
Why solid line does not appear?
Here is the data myfile.mat
I strongly suspect that your data arrays have a shape of (N, 1) ie [[0], [0], ...] which matplotlib in broadcasting (correctly) to N 1-point lines.
Try:
fig, ax = plt.subplots(1, 1)
ax.plot(x.flatten(), u0.flatten())
plt.show()