0

I was trying to create a plot with seaborn, but I faced an error:

*** ValueError: If using all scalar values, you must pass an index

In my program I have read an output file from XFOIL and was trying to plot its results to check it out.

XFOIL File format:

#      x          Cp  
     1.00000    0.24276
     0.99818    0.23883
     0.99591    0.22657
     0.99342    0.21421
     0.99066    0.20128
     0.98759    0.18802
     0.98413    0.17434
     0.98020    0.16018
     0.97569    0.14544
     0.97044    0.12999
     0.96429    0.11374
     0.95703    0.09661
### **(the file is big, and I will not transcript it completely here)** ###

I decided to create a dataframe to enable the plotting process easily.

lst = fl.readlines()
lst_splt = [ s.replace('#','').split() for s in lst] 
cp = pd.DataFrame.from_records(lst_splt[1:], columns=lst_splt[:1]).astype(float)

and finally I tried to plot it using seaborn:

sns.lineplot(x='x',y='Cp', data=cp)

but as I said on the beginning of the question, an error appeared:

*** ValueError: If using all scalar values, you must pass an index

What can I do to fix this error?

4
  • Could you try to add the index=[0] into the argument DataFrame.from_records(data, index=[0]) ? I can't replicate the scenario you have but that has worked for me previously. Commented Apr 20, 2021 at 9:35
  • Did you try to check that the DataFrame looks like what you expect it to? Does it? Did you try to check (for example, by reading the documentation) that Seaborn wants the data arranged that way? What happened when you tried copying and pasting If using all scalar values, you must pass an index into a search engine? Commented Apr 20, 2021 at 9:44
  • Are you sure the error appears on sns.lineplot and not on the unusual looking pd.DataFrame.from_records. Can you print out cp.head() just after the dataframe creation? Commented Apr 20, 2021 at 10:16
  • with cp = pd.read_csv(flname,'r', sep='\s+',skiprows=(3), header=None, index=[0]) the error *** TypeError: read_csv() got multiple values for argument 'sep' persists on read cp. I didn"t managed to get to sns.lineplot with this modification Commented Apr 20, 2021 at 11:03

2 Answers 2

2

Not sure why you are having this error, but you can simply do:

import matplotlib.pyplot as plt

plt.plot(cp["x"], cp["Cp"])
plt.show()

EDIT: After some experimentation, it seems that your method for creating the dataframe is probably the culprit. You can replace it with:

cp = pd.read_csv(filename, sep="\s+", skiprows=2, names=["x", "Cp"])
# Make sure that you have the right value for skiprows (should ignore the header and that's it)

# Then this works:
sns.lineplot(x="x", y="Cp", data=cp)
Sign up to request clarification or add additional context in comments.

6 Comments

Seems to me that this does not answer OP specific question which is to deal with his XFOIL file format.
Using the first method you presented works properly. I had already tried that before. But I am still curious about the error. I tried something similar to that wit seaborn and the error persisted.
Yes, have you tried to replace the file opening > read into dataframe with the function pd.read_csv as mentioned in my post? This should work for your file format and give you the result you want
About the second process, I tried and It worked! Thanks a lot!
Remove "r" (second argument), it has no place there...
|
1

The problem is related to the columns argument passed to the DataFrame constructor.

When printing lst_splt[:1], which is the value you pass to the columns argument, I get this:

print(lst_splt[:1])
# [['x', 'Cp']]

The Dataframe constructor in this case needs a flat list, not a nested one. The problem is solved when you change lst_splt[:1] to lst_splt[:1][0] which when printed gives of course:

print(lst_splt[:1][0])
# ['x', 'Cp']
The modified verrsion of your code below works fine:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

fl = open('data.txt', 'r')

lst = fl.readlines()
lst_splt = [ s.replace('#','').split() for s in lst]
cp = pd.DataFrame.from_records(lst_splt[1:], columns=lst_splt[:1][0]).astype(float)

sns.lineplot(data=cp, x='x',y='Cp')

plt.show()

out: enter image description here

1 Comment

I liked the approach you proposed! Thanks a lot! It will help me in some other problems too!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.