Drawing Sinus curve in Python

F

Farzad Torabi

Hi Experts

I am trying to draw a sine curve in Python , well first I had a script that i could draw a function curve in this way :

xMax = 25.0
points = []
for i in range(100):
x = (float(i)/99)*xMax
y = math.sqrt(x)
points.append([x,y])

s.Spline(points=points)


first i have questions that : what does the line x = (float(i)/99)*xMax do ? why do we multiply it by

and then when I wanted to draw a sine curve I found this one :

import math

for angle in range(????):
y = math.sin(math.radians(angle))
print(y)

first , here instead of ???? can we put 2*pi ?

second i wanted to try this method instead:

xMax = pi
Lamda = 200
points = []
for i in range(Lamda):
x = (float(i)/99)*xMax
y = math.sin(x)
points.append([x,y])

it actually works much better and creates an actual sine curve but the lengths are not really what i want , also if i want to draw a straight line I use this command :

xMax = 1
Lamda = 200
points = []
for i in range(Lamda):
x = (float(i)/99)
y = xMax
points.append([x,y])

but then the problem will be that I can not control the length of this line and the sine curve , that should be equal
 
S

Steven D'Aprano

Hi Experts

I am trying to draw a sine curve in Python , well first I had a script
that i could draw a function curve in this way :

xMax = 25.0
points = []
for i in range(100):
x = (float(i)/99)*xMax
y = math.sqrt(x)
points.append([x,y])

s.Spline(points=points)

What is s? Where does it come from?


first i have questions that : what does the line x = (float(i)/99)*xMax
do ? why do we multiply it by

In older versions of Python, division / with integer arguments does
integer division, like C, instead of calculator division. For example:

1/2 => returns 0

instead of 1/2 returning 0.5 like a calculator does. In these older
versions of Python, you can fix that by converting one of the arguments
to a float first:

1/2.0 => 0.5

So "float(i)/99" converts the loop index i to a float, then divides by
99. An easier way to get the same result is "i/99.0".

Then, multiplying by xMax simply scales the result to be between 0 and
xMax, in this case 25.0. Look at the results:

when i = 0, x = 0/99.0*25 = 0.0
when i = 99, x = 99/99.0*25.9 = 25.0

every other value of i gives a corresponding value between 0 and 25.

and then when I wanted to draw a sine curve I found this one :

import math

for angle in range(????):
y = math.sin(math.radians(angle))
print(y)

first , here instead of ???? can we put 2*pi ?


No. The Python built-in range() function only accepts integer values. It
is quite tricky to *accurately* produce floating point ranges. While it
is easy to make a floating point range, it is much harder to make it
accurate. You can see some discussion about the problem, and some sample
code, here:

http://code.activestate.com/recipes/577068
http://code.activestate.com/recipes/577878
http://code.activestate.com/recipes/577881



second i wanted to try this method instead:

xMax = pi
Lamda = 200
points = []
for i in range(Lamda):
x = (float(i)/99)*xMax
y = math.sin(x)
points.append([x,y])

it actually works much better and creates an actual sine curve but the
lengths are not really what i want , also if i want to draw a straight
line I use this command :

xMax = 1
Lamda = 200
points = []
for i in range(Lamda):
x = (float(i)/99)
y = xMax
points.append([x,y])

In this example, you are calculating points from a straight line. x
varies from 0.0 to 2.0202 in steps of 1/99, and y is always the same
value, 1.

but then the problem will be that I can not control the length of this
line and the sine curve , that should be equal

You have to get the maths right, otherwise the graph will be wrong.
 
D

Dennis Lee Bieber

Hi Experts

I am trying to draw a sine curve in Python , well first I had a script that i could draw a function curve in this way :

xMax = 25.0
points = []
for i in range(100):
x = (float(i)/99)*xMax
y = math.sqrt(x)
points.append([x,y])

s.Spline(points=points)


first i have questions that : what does the line x = (float(i)/99)*xMax do ? why do we multiply it by

{Presuming Python 2.x}

The easiest way to find out what the line is doing is to just add a few
print statements:
import math
xMax = 25.0
point = []
for i in range(100):
.... x = (i / 99.0) * xMax
.... y = math.sqrt(x)
.... print "%5d\t%10.6f\t%10.6f" % (i, x, y)
....
0 0.000000 0.000000
1 0.252525 0.502519
2 0.505051 0.710669
3 0.757576 0.870388
4 1.010101 1.005038
5 1.262626 1.123666
6 1.515152 1.230915
7 1.767677 1.329540
8 2.020202 1.421338
9 2.272727 1.507557
10 2.525253 1.589104
11 2.777778 1.666667
12 3.030303 1.740777
13 3.282828 1.811858
14 3.535354 1.880254
15 3.787879 1.946247
16 4.040404 2.010076
17 4.292929 2.071939
18 4.545455 2.132007
19 4.797980 2.190429
20 5.050505 2.247333
21 5.303030 2.302831
22 5.555556 2.357023
23 5.808081 2.409996
24 6.060606 2.461830
25 6.313131 2.512595
26 6.565657 2.562354
27 6.818182 2.611165
28 7.070707 2.659080
29 7.323232 2.706147
30 7.575758 2.752409
31 7.828283 2.797907
32 8.080808 2.842676
33 8.333333 2.886751
34 8.585859 2.930164
35 8.838384 2.972942
36 9.090909 3.015113
37 9.343434 3.056703
38 9.595960 3.097735
39 9.848485 3.138230
40 10.101010 3.178209
41 10.353535 3.217691
42 10.606061 3.256695
43 10.858586 3.295237
44 11.111111 3.333333
45 11.363636 3.370999
46 11.616162 3.408249
47 11.868687 3.445096
48 12.121212 3.481553
49 12.373737 3.517632
50 12.626263 3.553345
51 12.878788 3.588703
52 13.131313 3.623715
53 13.383838 3.658393
54 13.636364 3.692745
55 13.888889 3.726780
56 14.141414 3.760507
57 14.393939 3.793935
58 14.646465 3.827070
59 14.898990 3.859921
60 15.151515 3.892495
61 15.404040 3.924798
62 15.656566 3.956838
63 15.909091 3.988620
64 16.161616 4.020151
65 16.414141 4.051437
66 16.666667 4.082483
67 16.919192 4.113295
68 17.171717 4.143877
69 17.424242 4.174236
70 17.676768 4.204375
71 17.929293 4.234300
72 18.181818 4.264014
73 18.434343 4.293523
74 18.686869 4.322831
75 18.939394 4.351941
76 19.191919 4.380858
77 19.444444 4.409586
78 19.696970 4.438127
79 19.949495 4.466486
80 20.202020 4.494666
81 20.454545 4.522670
82 20.707071 4.550502
83 20.959596 4.578165
84 21.212121 4.605662
85 21.464646 4.632995
86 21.717172 4.660169
87 21.969697 4.687184
88 22.222222 4.714045
89 22.474747 4.740754
90 22.727273 4.767313
91 22.979798 4.793725
92 23.232323 4.819992
93 23.484848 4.846117
94 23.737374 4.872102
95 23.989899 4.897948
96 24.242424 4.923660
97 24.494949 4.949237
98 24.747475 4.974683
99 25.000000 5.000000
It is scaling the range 0..99 into 0.0..25.0.

NOTE: I used (i / 99.0) since the compiler, after your float(i), is
going to have to convert the integer 99 into a float before doing the
division -- so I just provided the constant as a float ahead of time, and I
let the compiler convert the integer i to a float on its own.
and then when I wanted to draw a sine curve I found this one :

import math

for angle in range(????):
y = math.sin(math.radians(angle))
print(y)

first , here instead of ???? can we put 2*pi ?

Did you try?

Short answer: no... The range() function only works with integers. You
could, however, scale it to a value providing enough steps, and then divide
by the scaling factor to get the actual value.
.... x = i / 100.0
.... y = math.sin(x)
.... print "%5d\t%10.6f\t%10.6f" % (i, x, y)
....
0 0.000000 0.000000
1 0.010000 0.010000
2 0.020000 0.019999
3 0.030000 0.029996
4 0.040000 0.039989
5 0.050000 0.049979
6 0.060000 0.059964
7 0.070000 0.069943
8 0.080000 0.079915
9 0.090000 0.089879
10 0.100000 0.099833
11 0.110000 0.109778
12 0.120000 0.119712
13 0.130000 0.129634
14 0.140000 0.139543
15 0.150000 0.149438
16 0.160000 0.159318
17 0.170000 0.169182
18 0.180000 0.179030
19 0.190000 0.188859
20 0.200000 0.198669
21 0.210000 0.208460
22 0.220000 0.218230
23 0.230000 0.227978
24 0.240000 0.237703
25 0.250000 0.247404
...
620 6.200000 -0.083089
621 6.210000 -0.073120
622 6.220000 -0.063143
623 6.230000 -0.053160
624 6.240000 -0.043172
625 6.250000 -0.033179
626 6.260000 -0.023183
627 6.270000 -0.013185


second i wanted to try this method instead:

xMax = pi
Lamda = 200
points = []
for i in range(Lamda):
x = (float(i)/99)*xMax
y = math.sin(x)
points.append([x,y])

it actually works much better and creates an actual sine curve but the lengths are not really what i want , also if i want to draw a straight line I use this command :

xMax = 1
Lamda = 200
points = []
for i in range(Lamda):
x = (float(i)/99)
y = xMax
points.append([x,y])

but then the problem will be that I can not control the length of this line and the sine curve , that should be equal

Well, consider -- the longest "x" value in the first is going to be
6.314918566306756

but the longest "x" in the second is just

To plot multiple curves on the same horizontal scale, the formula
controlling the value of "x" has to be the SAME. Moreover, for a straight
line, any decent plotting package should only need the first and last
points of the line, so the whole for-loop can be extracted out:

line = [ [0.0 / 99.0 * math.pi, xMax],
[199.0 / 99.0 * math.pi, xMax] ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top