How to plot a basic sine graph on matplotlib - python-3.x

HW problem:
Use matplotlib to plot 𝑠𝑖𝑛(𝑥) for x ∈ [ 0 , 𝜋/4 , 𝜋/2 , 3𝜋/4 ... 2𝜋 ]. Use both orange points and a green line.
notes in class don't talk about how to set axes or colours; I'm still trying to wrap my head around how to use Stack Overflow, please help!
Following code is what I have so far, but I want to add the orange points... If I need to totally change my code, I am okay with that.
x = [ (n*(pi/4)) for n in range(10) ]
a = [ sin(theta) for theta in x ]
plt.plot(x, a, 'g-', label='sine')
plt.axis([0, (2*pi), -1, 1.0])
plt.show()

Take a look at the documentation for plot. In particular, look at the "Other Parameters" section, and the list of keyword arguments. Every option you need is listed there.

Related

2D plot of x,y,z points in Python without Matplotlib

I have a set of 3d points (I generate the positions of planets and moons in a stellar system from Keplers equations) I have the coordinates of all points as x,y,z, where the central star is 0,0,0. The code to produce the points works perfectly.
However, at the moment I plot a visualisation of this system from above - so I just ignore the z component for the purposes of visualisation and plot the x and y to the canvas as-is. This works as intended.
How would I generate x and y coordinates for plotting to the canvas that take into account the z coordinate, so that I can plot a view from another angle apart from directly above?
The only library I can use apart from the standard one would be numpy. I cannot use Matplotlib.
edit thanks to the comments I can now clarify with some psudocode.
Assume I have a bunch of points that have an xyz position.
What I currently do:
canvas.plot(point.x)
canvas.plot(point.y)
ignoring point z - so that it is as if all z's are 0 and it is viewed from 'above'
So that I can use my current plotting code - which takes into account scale and offsets to do with the canvas, I need new x and y coordinates that are as if the view is from another angle other than 'above'.
It seems from the helpful comments what I have to do is rotate the whole coordinate system so that it has a new z axis that is a result of a rotation of the whole system about the x and y axis.
Something like the following psudocode would do.
def rotate_about_axis(x_rotation_degrees, y_rotation_degrees, point.x, point.y, point.z):
new_plot_x = canvas_point_to_plot after magic code to rotate coordinates x_rotation_degrees about x axis
new_plot_y = canvas_point_to_plot after magic code to rotate coordinates y_rotation_degrees about y axis
return new_plot_x, new_plot_y
Then I could apply this to all the points I plot.
How would I do this in python?
I have come up with an answer, I hope it helps someone.
import numpy, math
def rotate_about_axis(x_rotation_degrees, y_rotation_degrees, point_x, point_y, point_z):
xrads = math.radians(x_rotation_degrees)
yrads = math.radians(y_rotation_degrees)
rotation = [xrads, yrads, 0]
rotation_angle = numpy.linalg.norm(rotation)
norm_rotation = rotation / numpy.linalg.norm(rotation)
base_points = [point_x, point_y, point_z]
points = numpy.dot(base_points, norm_rotation) * norm_rotation
points_difference = base_points - points
points_transform = numpy.cross(norm_rotation, base_points)
rotated_points = points + points_difference * numpy.cos(rotation_angle) + points_transform * numpy.sin(rotation_angle)
rotated_point_x = rotated_points[0]
rotated_point_y = rotated_points[1]
return(rotated_point_x, rotated_point_y)

Get rid of the spaces histogram matplotlib [duplicate]

I'm making a bar chart in Matplotlib with a call like this:
xs.bar(bar_lefts, bar_heights, facecolor='black', edgecolor='black')
I get a barchart that looks like this:
What I'd like is one with no white gap between consecutive bars, e.g. more like this:
Is there a way to achieve this in Matplotlib using the bar() function?
Add width=1.0 as a keyword argument to bar(). E.g.
xs.bar(bar_lefts, bar_heights, width=1.0, facecolor='black', edgecolor='black').
This will fill the bars gaps vertically.
It has been 8 years since this question was asked, and the matplotlib API now has built-in ways to produce filled, gapless bars: pyplot.step() and pyplot.stairs() with the argument fill=True.
See the docs for a fuller comparison, but the primary difference is that step() defines the step positions with N x and N y values just like plot() would, while stairs() defines the step positions with N heights and N+1 edges, like what hist() returns. It is a subtle difference, and I think both tools can create the same outputs.
Just set the width 1 over the number of bars, so:
width = 1 / len(bar_lefts)
xs.bar(bar_lefts, bar_heights, width=width, color='black')
You can set the width equal to the distance between two bars:
width = bar_lefts[-1] - bar_lefts[-2]
xs.bar(bar_lefts, bar_heights, width=width)

plotting simplex method in Maxima

im having trouble plotting the results of simplex method used for linear programing in Maxima
i used
minimize_lp(-4*x-5*y,[5*x+4*y<=40, x+4*y<=32, 5*x<=30]);
to solve the problem but now i need to plot this
tried this:
wxplot2d(minimize_lp(-4*x-5*y,[5*x+4*y<=40, x+4*y<=32, 5*x<=30]),[x,-10,10],[y,-10,10]);
all i get is "expression evaluates to non-numeric value everywhere in plotting range" and "nothing to plot" messages
i dont really use Maxima, im not very familiar with it,
its an assigment for a course, any help would be great
Graphical solution for a linear optimization problem subject to constraints
To plot the inequalities and the feasible set I did the following:
Step 1 – solving algebraically using minimize_lp()
load("simplex")$
minimize_lp(
-4*x-5*y,[
5*x+4*y<=40,
x+4*y<=32,
5*x<=30,
x>=0,y>=0
]
);
which yields
%o2) [-91/2,[y=15/2,x=2]]
Step 2 – extracting the coordinates of the optimizing point from %o2
soln: %o2$
c4sol: soln[2]$
x_c: rhs(c4sol[2])$
y_c: rhs(c4sol[1])$
pOpt: [x_c,y_c];
This outputs
(%o7) [2,15/2]
the coordinates of the optimizing point pOpt in a list that we later need for plotting.
Step 3 – defining the feasible set
We know from minimize_lp() that f(x,y) is minimized at (x=2,y=15/2) with
f=-91/2. So we rewrite the target function as -4x-5y=-91/2
tfm: solve(-4*x-5*y=-91/2,y)$
Next we use the restriction r1,r2,r3 to define the the bounderies of the feasible set by turning the inequalities into equalities and solving for the dependent variables:
r1: solve(5*x+4*y=40,y)$
r2: solve(x+4*y=32,y)$
r3: solve(5*x=30,x)$
We then create a list L containing:
L: [ev(y,tfm), ev(y,r1), ev(y,r2), ev(x,r3)];
which yields:
(%o12) [-(8*x-91)/10,-(5*x-40)/4,-(x-32)/4,6]
Step 4 – The plots
We use plot2d() for quick'n'dirty sketches:
plot2d(L,[x,1.5,5.25],[y,5,8.25])$
For the final plot we use draw2d
draw2d(
proportional_axes=xy ,
xrange = [1.5,5.25],
yrange = [5.00,8.25],
point_type = filled_circle, point_size=1.25,
color = black,
points(pOpt),
label(["pOpt = (2,15/2)", 2.50, 7.65]),
key = "tfMin=-91/2",
line_width = 2,
color = steelblue4,
explicit(ev(y,tfm ), x,0,12.25),
key = "r1",
line_width = 1.5,
color = DeepPink3,
explicit(ev(y,r1), x,0,12.25),
key = "r2",
line_width = 1.5,
color = cyan4,
explicit(ev(y,r2), x,0,12.25),
key = "r3",
line_width = 1.5,
color = orange,
explicit(ev(x,r3), x,0,12.25),
key = "feasible set",
border = false,
fill_color = LightPink2,
polygon([[3.20,6],[2,7.5],[3.9,6]])
)$
Hope this helps, after all these years.
Cheers
Tilda

Doubts in histogram in python: frequency graph [duplicate]

I have count data (a 100 of them), each correspond to a bin (0 to 99). I need to plot these data as histogram. However, histogram count those data and does not plot correctly because my data is already binned.
import random
import matplotlib.pyplot as plt
x = random.sample(range(1000), 100)
xbins = [0, len(x)]
#plt.hist(x, bins=xbins, color = 'blue')
#Does not make the histogram correct. It counts the occurances of the individual counts.
plt.plot(x)
#plot works but I need this in histogram format
plt.show()
If I'm understanding what you want to achieve correctly then the following should give you what you want:
import matplotlib.pyplot as plt
plt.bar(range(0,100), x)
plt.show()
It doesn't use hist(), but it looks like you've already put your data into bins so there's no need.
The problem is with your xbins. You currently have
xbins = [0, len(x)]
which will give you the list [0, 100]. This means you will only see 1 bin (not 2) bounded below by 0 and above by 100. I am not totally sure what you want from your histogram. If you want to have 2 unevenly spaced bins, you can use
xbins = [0, 100, 1000]
to show everything below 100 in one bin, and everything else in the other bin. Another option would be to use an integer value to get a certain number of evenly spaced bins. In other words do
plt.hist(x, bins=50, color='blue')
where bins is the number of desired bins.
On a side note, whenever I can't remember how to do something with matplotlib, I will usually just go to the thumbnail gallery and find an example that looks more or less what I am trying to accomplish. These examples all have accompanying source code so they are quite helpful. The documentation for matplotlib can also be very handy.
Cool, thanks! Here's what I think the OP wanted to do:
import random
import matplotlib.pyplot as plt
x=[x/1000 for x in random.sample(range(100000),100)]
xbins=range(0,len(x))
plt.hist(x, bins=xbins, color='blue')
plt.show()
I am fairly sure that your problem is the bins. It is not a list of limits but rather a list of bin edges.
xbins = [0,len(x)]
returns in your case a list containing [0, 100] Indicating that you want a bin edge at 0 and one at 100. So you get one bin from 0 to 100.
What you want is:
xbins = [x for x in range(len(x))]
Which returns:
[0,1,2,3, ... 99]
Which indicates the bin edges you want.
You can achieve this using matplotlib's hist as well, no need for numpy. You have essentially already created the bins as xbins. In this case x will be your weights.
plt.hist(xbins,weights=x)
Have a look at the histogram examples in the matplotlib documentation. You should use the hist function. If it by default does not yield the result you expect, then play around with the arguments to hist and prepare/transform/modify your data before providing it to hist. It is not really clear to me what you want to achieve, so I cannot help at this point.

How to produce X values of a stretched graph?

I'm trying to "normalize" monthly data in a way.
What I mean by that is, I need to take daily values and check the data from each month against the data in another month.
The only problem with this is that some months are longer than others. So I have come up with a way that I want to do this, but I'm kind of confused as to exactly how to do it...
Basically, I'm looking at this website: http://paulbourke.net/miscellaneous/interpolation/ and trying to transform each set of coordinates into a graph with 31 X- and Y-values (I would like to use the Cosine interpolator, but I'm still trying to figure out what to do with it).
Now, the X values have a function. I can pass in something like (1..28) and morph it into 31 values...simple enough code, something like this works for me:
def total = (1..30)
def days = 28
def resize = {x, y->
result = []
x.each{ result << (it * (y/x.size())}
return result
}
resize(total,days)
Which returns a list of 31 Y-values spanning from 0 to 28.
My question is: How do I translate a list of the corresponding Y values to these values? I'm having a really hard time wrapping my head around the concept and could use a little help.
My first thought was to simply run the Y-values through this function too, but that returns values that are all lower than the original input.
I'm looking for something that will retain the values at certain points, but simply stretch the graph out horizontally.
For example, at the x value at (1/3) of the graph's length, the value needs to be the same as it would be at (1/3) of the original graph's length.
Can anyone help me out on this? It's got me stumped.
Thanks in advance!
Not sure where the problem lies with this, so I made up some data
I think your algorithm is correct, and you only need to normalize the x-axis.
I came up with this code (and some plots) to demonstrate what I believe is the answer
Define some x and y values:
def x = 1..30
def y = [1..15,15..1].flatten()
Then, generate a list of xy values in the form: [ [ x, y ], [ x, y ], ...
def xy = [x,y].transpose()
If we plot this list, we get:
Then define a normalize function (basically the same as yours, but it doesn't touch the y value)
def normalize( xylist, days ) {
xylist.collect { x, y -> [ x * ( days / xylist.size() ), y ] }
}
Then we can normalize our list to 28 days
def normalxy = normalize( xy, 28 )
Now, if we plot these points, we get
As you can see, both plots have the same shape, they are just different widths...
Have I missed the point?

Resources