Skip first several rows when plotting a CSV-file - python

For a project at work I'm working on a code that reads a csv-file and generates a plot.
My problem is, I work with multiple csv-files but all of them contain 10-40 rows in the beginning, filled with device and sensor information.
I would wish for my code to detect where the first line of values are and to start reading the values from there into my array. But since my experience with Python is very low, I couldnt find a good solution.
If you can recommend me specific methods or change my code, feel free to comment.
Thanks to everyone taking their time to help me
import matplotlib.pyplot as plt
import csv
a = []
b = []
c = []
d = []
e = []
with open('PATH','r') as csvfile:
lines = csv.reader(csvfile, delimiter=',')
for row in lines:
a.append(float(row [0]))
b.append(float(row [1]))
#c.append(float(row [2]))
#d.append(float(row [3]))
#e.append(float(row [4]))
f = plt.figure()
f.set_figwidth(12)
f.set_figheight(8)
#plt.plot(X-Achse, Y-Achse, linewidth=* , color = ' ', label = " ")
plt.plot(a, b, linewidth=0.35, color = 'b', label = "Sensor 1")
#plt.plot(a, c, linewidth=0.35, color = 'g', label = "Sensor 2")
plt.title('Pressure Report', fontsize = 20)
plt.xlabel('Time(s)')
plt.ylabel('Pressure(bar)')
plt.grid()
plt.legend()
plt.show()

You can skip the lines using conditional statements as below:
count = 1
for row in lines:
if (count < 10 and count > 40):
a.append(float(row [0]))
b.append(float(row [1]))
count += 1

What is working for me are the following changes. It may not be the fastest and best solution, but it does what its supposed to.
import matplotlib.pyplot as plt
import csv
path = 'PATH'
line_number = 0
list_of_results = []
count = 1
a = []
b = []
c = []
d = []
e = []
with open(path, 'r') as read_obj:
for line in read_obj:
line_number += 1
if "0.000000000" in line:
list_of_results.append((line_number))
firstline = list_of_results[0]-1
with open(path,'r') as csvfile:
lines = csv.reader(csvfile, delimiter=',')
for row in lines:
if (count > firstline):
a.append(float(row [0]))
b.append(float(row [1]))
#c.append(float(row [2]))
#d.append(float(row [3]))
#e.append(float(row [4]))
count += 1
f = plt.figure()
f.set_figwidth(12)
f.set_figheight(8)
#plt.plot(X-Achse, Y-Achse, linewidth=* , color = ' ', label = " ")
plt.plot(a, b, linewidth=0.35, color = 'b', label = "Sensor 1")
#plt.plot(a, c, linewidth=0.35, color = 'g', label = "Sensor 2")
plt.title('Pressure Report', fontsize = 20)
plt.xlabel('Time(s)')
plt.ylabel('Pressure(bar)')
#plt.axis([x_min, x_max, y_min, y_max])
#plt.axis([350, 380, -6, 2.2])
plt.grid()
plt.legend()
plt.show()

Related

Matplotlib is making positives into negatives

I'm just trying to graph some simple data and whether I try to do it with plot or subplot it comes out the same. All values in my lists are positive but the y axis is acting like a number line with only positives.
import matplotlib.pyplot as plt
xVal = []
yVal1 = []
yVal2 = []
yVal3 = []
data = []
# load data
with open(r"path", 'r') as f:
data = f.readlines()
yVal1 = data[0].split(",")
yVal2 = data[1].split(",")
yVal3 = data[2].split(",")
del yVal1[-1]
del yVal2[-1]
del yVal3[-1]
print(yVal1)
print(yVal2)
print(yVal3)
# graph dem bois
xVal = [*range(0, len(yVal1))]
'''fig, ax = plt.subplots(3)
ax[0].plot(xVal, yVal1)
ax[0].set_title("pm5")
ax[1].plot(xVal, yVal2)
ax[1].set_title("pm7.5")
ax[2].plot(xVal, yVal3)
ax[2].set_title("pm10")
fig.suptitle("Particulate Levels over time")'''
plt.plot(xVal, yVal3)
plt.show()
As per the comment by Jody Klymak I converted the string lists into float lists and it worked.
fyVal1 = [float(x) for x in yVal1]

Left and Right alignment in pyplot legend [duplicate]

This question already has an answer here:
legend alignment in matplotlib
(1 answer)
Closed 2 years ago.
In the legend of my plot, I want to display the (best) values of the functions as well, next to the 'normal' legend.
My current try:
Which I have coded like this:
for j, pol in enumerate(pols):
val = vidics[1][pol]
axis[1,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_3).melt(), label = f'FI: {score_FI_3:.1f}', ax=axis[1,i])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_3).melt(), label = f'PO: {score_PO_3:.1f}', ax=axis[1,i])
The for loop creates the horizontal lines.
The sns lines create the blue and orange lines.
What I would like to have is that the scores (the values in the legend) are right aligned.
Doing this manually by adding spaces in the fstrings is not feasible as I've many of these small plots filled in a loop. I tried adding blanks/fills in the fstring, e.g. the following label for the second sns line:
label = f'{"PO": < 10}: {score_PO_3:.1f}'
Which adds blanks untill the string got a length of 10 (I think?). I thought If I would do that for all the strings, the right would align out but as not all the characters in the string have the same width this also does not work and looks ugly.
Any ideas?
Furthermore, a the larger code, for reference:
pols = ['optimal', 'preventive', 'corrective']
pol_label = ['VIoptm', 'VIprev', 'VIcorr']
vidics = [vi2, vi3, vi4]
labels = ['4', '5', '6', '7']
dics2_PO = [s4_PO_2, s5_PO_2, s6_PO_2, s7_PO_2]
dics2_FI = [s4_FI_2, s5_FI_2, s6_FI_2, s7_FI_2]
dics3_PO = [s4_PO_3, s5_PO_3, s6_PO_3, s7_PO_3]
dics3_FI = [s4_FI_3, s5_FI_3, s6_FI_3, s7_FI_3]
dics4_PO = [s4_PO_4, s5_PO_4, s6_PO_4, s7_PO_4]
dics4_FI = [s4_FI_4, s5_FI_4, s6_FI_4, s7_FI_4]
figlabel = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k','l']]
fig, axis = plt.subplots(3,4, figsize=(17,10))
st = ['-', '-.' , ':']
for i in range(4):
# 2 comp
dic2FI = dics2_FI[i]
dic2PO = dics2_PO[i]
r_FI_2 = dic2FI['ar']
r_PO_2 = dic2PO['ar']
t_PO_2 = np.array(dic2PO['t']).sum()
best_r_FI = np.array(dic2FI['best_r'])
best_r_PO = np.array(dic2PO['best_r'])
score_FI_2 = best_r_FI.mean()
score_PO_2 = best_r_PO.mean()
sd_FI_2 = best_r_FI.std()
sd_PO_2 = best_r_PO.std()
print(f'2comp, agent {labels[i]} FI : {score_FI_2:.1f} +- {sd_FI_2:.1f} ')
print(f'2comp, agent {labels[i]} PO : {score_PO_2:.1f} +- {sd_PO_2:.1f} ')
print(f'2comp, agent {labels[i]} PO , time: {t_PO_2:.0f}')
for j, pol in enumerate(pols):
val = vidics[0][pol]
axis[0,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_2).melt(), label = f'FI: {score_FI_2:.1f}', ax=axis[0,i])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_2).melt(), label = f'PO: {score_PO_2:.1f}', ax=axis[0,i])
axis[0,i].set_ylim((-30,-8))
axis[0,i].legend(loc='lower right')
axis[0,i].set_xlabel('Training Iterations')
axis[0,i].set_xticks([4,9])
axis[0,i].set_xticklabels(['50k', '100k'])
axis[0,i].set_title(f'{figlabel[0][i]}) 2 comp, agent {labels[i]}')
if i==0:
axis[0,i].set_ylabel('Average Reward')
else:
axis[0,i].set_ylabel('')
# 3 comp
dic3FI = dics3_FI[i]
dic3PO = dics3_PO[i]
r_FI_3 = dic3FI['ar']
r_PO_3 = dic3PO['ar']
t_PO_3 = np.array(dic3PO['t']).sum()
best_r_FI = np.array(dic3FI['best_r'])
best_r_PO = np.array(dic3PO['best_r'])
score_FI_3 = best_r_FI.mean()
score_PO_3 = best_r_PO.mean()
sd_FI_3 = best_r_FI.std()
sd_PO_3 = best_r_PO.std()
print(f'3comp, agent {labels[i]} FI : {score_FI_3:.1f} +- {sd_FI_3:.1f} ')
print(f'3comp, agent {labels[i]} PO : {score_PO_3:.1f} +- {sd_PO_3:.1f} ')
print(f'3comp, agent {labels[i]} PO , time: {t_PO_3:.0f}')
for j, pol in enumerate(pols):
val = vidics[1][pol]
axis[1,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_3).melt(), label = f'FI: {score_FI_3:.1f}', ax=axis[1,i])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_3).melt(), label = f'PO: {score_PO_3:.1f}', ax=axis[1,i])
axis[1,i].set_ylim((-60,-15))
axis[1,i].legend(loc='lower right')
axis[1,i].set_xlabel('Training Iterations')
axis[1,i].set_xticks([4,9])
axis[1,i].set_xticklabels(['100k', '200k'])
axis[1,i].set_title(f'{figlabel[1][i]}) 3 comp, agent {labels[i]}')
if i==0:
axis[1,i].set_ylabel('Average Reward')
else:
axis[1,i].set_ylabel('')
# 4 comp
dic4FI = dics4_FI[i]
dic4PO = dics4_PO[i]
r_FI_4 = dic4FI['ar']
r_PO_4 = dic4PO['ar']
t_PO_4 = np.array(dic4PO['t']).sum()
best_r_FI = np.array(dic4FI['best_r'])
best_r_PO = np.array(dic4PO['best_r'])
score_FI_4 = best_r_FI.mean()
score_PO_4 = best_r_PO.mean()
sd_FI_4 = best_r_FI.std()
sd_PO_4 = best_r_PO.std()
print(f'4comp, agent {labels[i]} FI : {score_FI_4:.1f} +- {sd_FI_4:.1f} ')
print(f'4comp, agent {labels[i]} PO : {score_PO_4:.1f} +- {sd_PO_4:.1f} ')
print(f'4comp, agent {labels[i]} PO , time: {t_PO_4:.0f}')
for j, pol in enumerate(pols):
val = vidics[2][pol]
axis[2,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_4).melt(), label = f'FI: {score_FI_4:.1f}', ax=axis[2,i])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_4).melt(), label = f'PO: {score_PO_4:.1f}', ax=axis[2,i])
axis[2,i].set_ylim((-70,-20))
axis[2,i].legend(loc='lower right')
axis[2,i].set_xlabel('Training Iterations')
axis[2,i].set_xticks([4,9])
axis[2,i].set_xticklabels(['200k', '400k'])
axis[2,i].set_title(f'{figlabel[2][i]}) 4 comp, agent {labels[i]}')
if i==0:
axis[2,i].set_ylabel('Average Reward')
else:
axis[2,i].set_ylabel('')
plt.tight_layout()
Which creates the following figure:
Take a look at where you assign the label value:
label=f'{pol_label[j]}: {val:.1f}'
In this format all is left aligned. It's comparabale with e.g.:
print('{:<2}: {:<8}'.format(*['label','value']))
which means something like, 'left align everything, but let the first word have an available space of 2 (counting from left), and the second a space of 8'
To fix I would try to keep the first word left-aligned but the second right-aligned, given an appropriate available space. In the above line, simply change the second sign, and possibly the space:
print('{:<2}: {:>8}'.format(*['label','value']))
to achieve (output):
label: value
(Label is left aligned, value is right-aligned)
reference

improve fit of polyval and polyfit

Can anyone help me to get a better fit on this curve? The plot shows test data for compression on an elastomer. The blue dots are the data, the red line is the 3rd order fit. If I increase the order of the fit the situation doesn't improve much.
I can supply the test data file if desired (There are 236 rows and 3 columns).
My code is given here:
import csv
import numpy as np
from matplotlib import pyplot as plt
import numpy.polynomial.polynomial as poly
from itertools import islice
with open('neoprene1.csv') as f:
readCSV = csv.reader(f, delimiter=',')
Cs = []
Rs = []
for row in islice(readCSV,1,None):
R = row[1] if row[1] != '' else 0.0 # Strain
C = row[2] if row[2] != '' else 0.0 # Stress
Rs.append(R)
Cs.append(C)
q = np.array([Rs],dtype = float).transpose()
s = np.array([Cs],dtype = float).transpose()
q1 = q[:,0]
s1 = s[:,0]
plt.cla()
z = poly.polyfit(q1,s1,3)
zz = poly.polyval(q,z)
plt.title('Neoprene True Stress-Strain')
plt.xlabel('Strain (%)')
plt.ylabel('Stress (MPa)')
aa = plt.plot(s1,zz,'r-', label = 'Fitting function')
bb = plt.plot(s1,q1,'bo', label = 'Raw data')

Only last graph is getting pasted in pdf file in python

I am reading the parameters from different CSV files and creating the graphs after comparing the parameters across the CSVs. The problem is only last graph is getting pasted in PDF for the last parameter.
with PdfPages('example.pdf') as pdf:
for arg in sys.argv[1:]:
file_reader= open(arg, "rt", encoding='ascii')
read = csv.reader(file_reader)
for row in read:
if operation_OnDut in row:
column_Result = row[10]
resultOfOperations_OnDut_List.append(column_Result)
buildNumber = row[0]
buildName_List.append(buildNumber)
N = len(resultOfOperations_OnDut_List)
ind = np.arange(N)
#Draw graph for operations performed in that TEST CASE
y = resultOfOperations_OnDut_List
width = .1
fig, ax = plt.subplots()
plt.bar(ind, y, width, label = column_Parameters, color="blue")
plt.xticks(ind, buildName_List)
plt.title("Performance and Scale")
plt.ylabel('Result of Operations')
plt.xlabel('Execution Builds')
plt.legend()
plt.tight_layout()
pdf.savefig()
plt.close()
resultOfOperations_OnDut_List = []
buildName_List = []
You probably got the indentation wrong...
Try
with PdfPages('example.pdf') as pdf:
for arg in sys.argv[1:]:
file_reader= open(arg, "rt", encoding='ascii')
read = csv.reader(file_reader)
for row in read:
if operation_OnDut in row:
column_Result = row[10]
....
# one level deeper
N = len(resultOfOperations_OnDut_List)
ind = np.arange(N)
#Draw graph for operations performed in that TEST CASE
...
Note that the section starting with N = len(resultOfOperations_OnDut_List) has been shifted four spaces to the left to be within the first for loop. If you want it to be within the second for loop add four more spaces.

How to draw line between point using python

How to draw line between 2 or 3 point.
I have 2 text file, first text file is list of posisition for each point.
point long lat
A 115 12
B 89 13
C 100 13
etc.
and the second file is like this:
3, 4
A, B, C
R, X, Y
V, P, O
J, M, N
2, 3
Q, S
H, K
T, W
4, 1
E, D, F, G
And I want draw the lines like this pic:
Actually, I'm not sure with my code. This is my code::
import psycopg2
import psycopg2.extensions
import matplotlib.pyplot as plt
import itertools
import collections
import numpy as np
def readRules(_dir):
#_dir = r'D:\s2\semester 3\tesis\phyton\hasil\Hasil_20160116_09.12.11'
mydict = {}
with open(os.path.join(_dir, 'rule3.csv'), 'rb') as testfile:
for line in testfile:
# first line is the next record "matrix size"
columns, rows = (int(x) for x in strip_comment(line).split(','))
# next line is the header for this record
key = tuple(strip_comment(next(testfile)).split(','))
# the next lines are the rows for this record
vals = [tuple(int(x) for x in strip_comment(next(testfile)).split(','))
for _ in range(rows)]
mydict[key] = vals
#print(mydict)
return mydict
data=getDataReference(cur) # to get location for each point
myPoints={}
myLines=[]
mydict=readRules(_dir)
# print "value :", mydict.values()
# print "key:", mydict.keys()
for value in mydict.values():
for x in value:
for s in range(len(x)):
myPoints[x[s]]= data[x[s]][0]
#print x[s]
if len(x)>1:
myLines.append(x)
myPoints_reversed = collections.defaultdict(list)
for number, string in myPoints.items():
myPoints_reversed[string].append(number)
colors = plt.cm.Spectral(np.linspace(0, 1, len(myPoints_reversed)))
myplt={}
for k, col in zip(myPoints_reversed.keys(),colors):
Long=[]
Lat=[]
for x in myPoints_reversed[k]:
Long.append(data[x][2])
Lat.append(data[x][1])
myplt[k] =plt.plot( Lat,Long , 'o', markerfacecolor=col, markeredgecolor='k', markersize=10, label=k)
#plt.legend(myplt,myPoints_reversed.keys(),loc=3,ncol=2, mode="expand", borderaxespad=0.)
plt.legend(loc =3,ncol=2, borderaxespad=0.)
#print myLines
#plt.plot(getListLat(myPoints.keys(),data), getListLong(myPoints.keys(),data),'o')
for point in myPoints:
#plt.annotate(getName(point,data), xy=getLatLong(point,data)) #Print name of point
plt.annotate(point, xy=getLatLong(point,data))
for line in myLines:
plotLine(line[0],line[1],data)
plt.show()

Categories