0

As reported below, I have this oscilloscope that saves generated data in .csv, but it saves them as strings. I think, as a beginner with Python, that all the problem is around the write csv function. Infact, I tried to change there "str" with "float" but nothing seems to change, indeed nothing work ....How should I do this? Some suggestion?

import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation

PATH_TO_CSV = "dataTank.csv"

class Scope(object):
    def __init__(self, ax, maxt=2, dt=0.02):
        self.ax = ax
        self.dt = dt
        self.maxt = maxt
        self.tdata = [0]
        self.ydata = [0]
        self.line = Line2D(self.tdata, self.ydata)
        self.ax.add_line(self.line)
        self.ax.set_ylim(-.1, 1.1)
        self.ax.set_xlim(0, self.maxt)

    def write_to_csv(self, t, y):
        line_to_be_written = str(t)+","+str(y)+"\n"
        with open(PATH_TO_CSV, "a") as csv:
            csv.write(line_to_be_written)

    def update(self, y):
        lastt = self.tdata[-1]
        if lastt > self.tdata[0] + self.maxt:  # reset the arrays
            self.tdata = [self.tdata[-1]]
            self.ydata = [self.ydata[-1]]
            self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt)
            self.ax.figure.canvas.draw()
        t = self.tdata[-1] + self.dt
        self.tdata.append(t)
        self.ydata.append(y)
        self.line.set_data(self.tdata, self.ydata)
        self.write_to_csv(t, y)
        return self.line,

def emitter(p=0.03):
    'return a random value with probability p, else 0'
    while True:
        v = np.random.rand(1)
        if v > p:
            yield 0.
        else:
            yield np.random.rand(1)

# Fixing random state for reproducibility
np.random.seed(19680801)

fig, ax = plt.subplots()
scope = Scope(ax)

# pass a generator in "emitter" to produce data for the update func
ani = animation.FuncAnimation(fig, scope.update, emitter, interval=10,
                              blit=True)

plt.show()

Thank you so much!

3 Answers 3

1

Assuming you just want to print the floating point numbers inside your csv function properly, there are answers for that here: https://stackoverflow.com/a/8885688/9898968

Just use a floating point specifier like: {:X.1f} inside the format string. X being the overall character width of the field in the csv. 1 in this case the decimal points printed.

line_to_be_written = "{:5.1f},[{:5.1f}]\n".format(float(t), float(y))

EDIT: Added float conversion to the format arguments. See here for details

Sign up to request clarification or add additional context in comments.

5 Comments

thank you dea @FloWil ...I tried It starts to work, then it stops and gives: line_to_be_written = "{:5.1f},[{:5.1f}]\n".format(t, y) ValueError: Unknown format code 'f' for object of type 'str'
@wundolab That depends on your input data then. The line I posted assumes you already get floats to the function. If it's still strings, try to convert them to float numbers. See Edit.
thank you...is it enough to add the function of the post written by "Cybernetic"?
def string_to_number(str): if("." in str): try: res = float(str) except: res = str elif(str.isdigit()): res = int(str) else: res = str return(res)
Really depends on how your input data looks like. If you only have floats as string in there the cast to float above should be enough. If its float and other data types in there you are properly better of to use some kind of the function you mentioned.
1

Instead of this,

line_to_be_written = str(t)+","+str(y)+"\n"

try doing it like this,

line_to_be_written = "{time},{value}\n".format(time = t, value = y if type(y)==float else y.item(0))

but, I'm not quite sure I understand what you really want to do. What do you mean by it saves them as strings?

Edit: I tried this, see if this is the result you want. I can't quite point out where y became a list numpy array in your code but that seems to be the problem


You can also try this,

def emitter(p=0.03):
'return a random value with probability p, else 0'
while True:
    v = np.random.rand(1)
    if v > p:
        yield 0.
    else:
        yield float(np.random.rand(1).item(0))

Instead of yielding a np.random.rand(1), you'll instead yield the items in it instead of the whole np array

8 Comments

thank you @Dave Mendoza for answer....I mean that in the .csv I see for the variable time (number in format 0.0) and for y as p it appear not 0.0 for example but [0.0].
I used your code but it seems, unfortunately, that it doesn't work :(
Oh it seems like then that it isn't a str, rather a list. lines_to_be_written = "{time},{value}\n".format(time = t, value = y if type(float) else y[0])
@wundolab check my edit on the post, see if that's how you want it. That's a partial fix tho so there can be a better fix
Sorry, this one should work: line_to_be_written = "{time},{value}\n".format(time = t, value = y if type(y) == float else y.item(0)), turns out it's a numpy array not a list. Also, I made a mistake in the type(float) it should be type(y) == float, I edited my post again to reflect that. See if that works
|
0

Solved! Thank you very much to @Dave Mendoza and @FloWill from your answers I solved doing a mixing!

    line_to_be_written = "{:5.1f},{:5.1f}\n".format(float(t), float(y))

Comments

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.