-1

I'm asking this question again because I have not gathered a clear answer for my question.

I have a set of equations:

ref_energy = (K-(C/2)comp(a)) + C/2
form_E2 = relaxed_E_per_atom - ref_energy(comp_x)

I need to have a python script use these two equations using the values in the txt file to generate another x and y columns of values that will plot those values.

This is the first few lines of my txt file. the config is the name of the structure associated with four values

comp(a),form_E,comp_x,relaxed_E_per_atom
0,0,0,-8.15382173
1,0,0.33333333,-5.25358563
0.5,0.18614484,0.2,-6.33922213
0.5,-0.69658919,0.2,-6.69231575
0.5,-0.70549249,0.2,-6.69587707

Below is my script but I keep getting errors such as

Traceback (most recent call last):
  File "attempt_#2.py", line 80, in <module>
    x.append(float(row[0]))
ValueError: could not convert string to float: 'comp(a)'

I assume the x value isn't a numerical value in the configname, but not sure.

#!/bin/env/python
import numpy as np
import matplotlib.pyplot as plt 
import csv

Columns = 'configname,comp(a),form_E,comp_x,relaxed_E_per_atom'.split(',')
testdata ='''\
comp(a),form_E,comp_x,relaxed_E_per_atom
0,0,0,-8.15382173
1,0,0.33333333,-5.25358563
0.5,0.18614484,0.2,-6.33922213
0.5,-0.69658919,0.2,-6.69231575
0.5,-0.70549249,0.2,-6.69587707
'''

reader = csv.DictReader(StringIO(testdata))
desired_cols = (tuple(row[col] for col in columns) for row in reader)   
x=[]
y=[]
K=-2.69028905
C=-32.65176322
with open('values2.txt','r') as csvfile:
        points = csv.reader(csvfile,delimiter=',')
        for row in points:
            x.append(float(row[0]))
            y.append(float(row[1]))
allpoints=np.loadtxt('hmm.csv',delimiter=',')
ref_energy = (Kend-(Cend/2))*comp(a) + Cend/2
form_E = relaxed_E_per_atom-ref_energy(comp_x)
plt.scatter(x,y, label='Energy')
plt.xlabel('Composition KxC',fontsize=24)
plt.ylabel('Formation Energy per carbon (eV)',fontsize=18)
plt.title('Convex Hull Potassium Graphite')
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.tight_layout()
plt.ylim(-0.08,0)
plt.xlim(0,1.01)
plt.show()
Jack Lee
  • 1
  • 4
  • 1
    The problem is that you're treating the header line as a row of data. So it tries to turn headers like `comp(a)` into floats, which obviously won't work. The simplest answer is to add `next(points) # skip header` right about the `for row in points:`. – abarnert May 31 '18 at 21:08
  • The attached dup is about editing a CSV file, rather than just reading it, but I think the answers explain nicely how to do what you want, why it's needed, and why it works. – abarnert May 31 '18 at 21:10
  • 1
    Also, I notice that you're creating a `DictReader` for `testdata`. You can do the same thing for `csvfile`. That will not just skip the headers, but actually use them, to give you a dict with nicely named columns for each row, instead of just a list. (Which is explained better in the second answer on the dup question—or just in the `csv` docs.) – abarnert May 31 '18 at 21:12
  • It worked but now it says, " x.append(float(row[0])) ValueError: could not convert string to float: 'form_E'" form_E is the second column – Jack Lee May 31 '18 at 21:23
  • Do you have a blank line before the header line? That's usually not considered valid for a CSV file, but I've seen lots of people write Python code that generates files like that anyway, so… Anyway, if that's the problem, you just need to skip _two_ lines at the start instead of one. – abarnert May 31 '18 at 21:25
  • no that's not the case. – Jack Lee May 31 '18 at 21:41
  • Then there's something else weird about your file or your code, and that something else weird is probably going to be something harder to guess (since we've already gone through the common/obvious problems), so you need to give us an [mcve] if you want anyone to debug it. – abarnert May 31 '18 at 21:57
  • When working with table data, you may want to use tool like `pandas`. Which simplifies greatly the workflow `import pandas as pd; df = pd.read_csv(s); df = df.rename(columns={'comp(a)': 'comp_a'}); # pandas doesnot like ( in column name K=-2.69028905; C=-32.65176322; df = df.eval('ref_energy = (@K-(@C/2) * comp_a) + @C/2'); df = df.eval('form_E2 = relaxed_E_per_atom - ref_energy * comp_x'); df` – phi May 31 '18 at 22:54

1 Answers1

1

Skip the first row

with open('values2.txt','r') as csvfile:
        points = csv.reader(csvfile,delimiter=',')
        next(points)
        for row in points:
            x.append(float(row[0]))
            y.append(float(row[1]))
mad_
  • 8,121
  • 2
  • 25
  • 40
  • It worked but now it says, " x.append(float(row[0])) ValueError: could not convert string to float: 'form_E'" form_E is the second column – Jack Lee May 31 '18 at 21:13
  • well next(points) should skip reading the first row. – mad_ May 31 '18 at 21:17
  • does the error have to do with my txt file containing five columns of data? or the error in x.append(float(row[0]))? – Jack Lee May 31 '18 at 21:22