beginning CS student here. I am trying to have python 2.7 draw a rectangle using a function that only has the turtle object, the upper left corner coordinates, and the lower right corner coordinates as arguments. I know there are simpler way of drawing a rectangle but I am trying to do it only using corner coordinates.
After running my current code I get the following:
TypeError: can't multiply sequence by non-int of type 'float'
I know this is probably something simple but I am having trouble figuring out what I'm doing wrong so any help would be appreciated.
My code is as follows:
from turtlegraphics import Turtle
def drawLine(t1,x1,y1,x2,y2):
t1.setWidth(1)
t1.setColor(0,0,0)
t1.up()
t1.move(x1,y1)
t1.down()
t1.move(x2,y2)
def rectangleSimple(t2,upperLeftPoint,lowerRightPoint):
t2.setWidth(1)
t2.setColor(0,0,0)
t2.up()
t2.move(upperLeftPoint)
t2.down()
t2.setDirection(270)
t2.move(lowerRightPoint[2])
t2.setDirection(0)
t2.move(lowerRightPoint)
t2.setDirection(90)
t2.move(upperLeftPoint[2])
t2.setDirection(180)
t2.move(upperLeftPoint)
def main():
t1 = Turtle()
x1 = 0
y1 = 0
x2 = 50
y2 = 0
drawLine(t1,x1,y1,x2,y2)
t2 = Turtle()
upperLeftPoint = (-100,50)
lowerRightPoint = (100,-50)
rectangleSimple(t2,upperLeftPoint,lowerRightPoint)
main()
I use the turtle module, not turtlegraphics but my guess is these two lines are at issue:
t2.move(lowerRightPoint[2])
t2.move(upperLeftPoint[2])
Your *Point variables are tuples with two values, X & Y, at indexes 0 & 1 but you're accessing the non-existent third value at index 2. There are many different ways to implement what you're trying to do, here's one using the turtle module that comes with Python:
from turtle import Turtle
X, Y = range(2)
def drawLine(t, x1, y1, x2, y2):
t.up()
t.width(1)
t.pencolor(1, 0, 0) # red
t.goto(x1, y1)
t.down()
t.goto(x2, y2)
def rectangleSimple(t, upperLeftPoint, lowerRightPoint):
t.up()
t.width(1)
t.pencolor(0, 1, 0) # green
t.goto(upperLeftPoint)
t.setheading(0) # East
t.down()
t.goto(lowerRightPoint[X], upperLeftPoint[Y])
t.right(90)
t.goto(lowerRightPoint)
t.right(90)
t.goto(upperLeftPoint[X], lowerRightPoint[Y])
t.right(90)
t.goto(upperLeftPoint)
if __name__ == "__main__":
from turtle import done
t1 = Turtle()
drawLine(t1, 0, 0, 50, 0)
t2 = Turtle()
upperLeftPoint = (-100, 50)
lowerRightPoint = (100, -50)
rectangleSimple(t2, upperLeftPoint, lowerRightPoint)
done()
Related
Python 3 and Django 1.11.15
Hi,
I'm using a plugin which returns an x and y position from an image besides usual image dimensions (width and height). I'd like to crop this image with sorl_thumbnail in Python using x and y position (like image cover on Facebook). I think there is a function, maybe like cropbox(), but I don't understand how it works. Please someone can help me, giving me an example of using this function or another solution to crop an image with these data.
Thanks to all.
Here is a sample of my code in models.py:
from sorl.thumbnail import default as sorl_thumbnail
def as_headline(self):
image = self.image
img_size = "600"
x = 133
y = 0
x2 = 328
y2 = 180
cropbox = (x, y, x2, y2)
return sorl_thumbnail.backend.get_thumbnail("path/to/file.jpg", img_size, cropbox=cropbox).url
I am trying to check distance by passing parameters to point class.But when i provide the user input,program later fails at calculation of distance point:
import math
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, point):
return math.sqrt((self.x-point.x)**2+ (self.y-point.y)**2)
class Circle(Point):
#classmethod
def envelops(self, shape):
if shape == "Circle":
r1 = float(input("Enter radius first circle:"))
r2 = float(input("Enter radius of second circle:"))
x1 = float(input("Enter first circle's x coordinate: "))
x2 = float(input("Enter second circle's x coordinate: "))
y1 = float(input("Enter first circle's y coordinate: "))
y2 = float(input("Enter second circle's y coordinate: "))
Point(x1,y1)
dist=(Point.distance(Point(x2,y2)))
if r1 > (r2 + dist):
print "First Circle envelops the second circle"
else:
pass
if __name__ == "__main__":
shape = 'Circle'
Circle.envelops(shape)
I get the following error on executing the file:
dist=(Point.distance(Point(x2,y2)))
TypeError: distance() takes exactly 2 arguments (1 given)
I need to get rid of this error urgently.Any help would be appreciated.
Change:
Point(x1,y1)
dist=(Point.distance(Point(x2,y2)))
to:
x = Point(x1,y1)
dist = x.distance(Point(x2,y2))
Explanation: distance is not a class method (static method) hence it should be called on an object of the class - not on the class itself. So the first call Point(x1,y1) should be assigned to a variable (here I used x) and then we'll use this Point object that we just created to measure the distance from the other point which is created on-the-fly: Point(x2,y2).
We could also create and save the other point:
x = Point(x1,y1)
y = Point(x2,y2)
dist = x.distance(y) # and now call it with both points
You have self as a parameter for distance. So the call wouldn't be Point.distance(x1, y2) but point1.distance(point2)
Also Point(x1, y1) doesn't really do anything. You need to assign that somewhere. Like point1 = Point(x1, y1)
I managed to create a function that with a given radius, starting point and a number of points. It will create a big circle and withing this circle it will create 4 small circles.
I want to add a grid on the background that will show the Y and X axis in TKinter every 100 pixels apart starting from the top left. The coordinate origin should be the top left corner.
For example if the screen is 300x300 then the window will have 3 lines (at 100, 200 and 300) on his X axis going from left to right and top up to bottom.
A grid as a coordinate system.
Example of how I create a normal line. I use a line class which contains 2 points start point and end point:
rootWindow = Tkinter.Tk()
rootFrame = Tkinter.Frame(rootWindow, width=1000, height=800, bg="white")
rootFrame.pack()
canvas = Tkinter.Canvas(rootFrame, width=1000, height=800, bg="white")
canvas.pack()
def draw_line(l):
"Draw a line with its two end points"
draw_point(l.p1)
draw_point(l.p2)
# now draw the line segment
x1 = l.p1.x
y1 = l.p1.y
x2 = l.p2.x
y2 = l.p2.y
id = canvas.create_line(x1, y1, x2, y2, width=2, fill="blue")
return id
This will create a grid on the canvas for you
import tkinter as tk
def create_grid(event=None):
w = c.winfo_width() # Get current width of canvas
h = c.winfo_height() # Get current height of canvas
c.delete('grid_line') # Will only remove the grid_line
# Creates all vertical lines at intevals of 100
for i in range(0, w, 100):
c.create_line([(i, 0), (i, h)], tag='grid_line')
# Creates all horizontal lines at intevals of 100
for i in range(0, h, 100):
c.create_line([(0, i), (w, i)], tag='grid_line')
root = tk.Tk()
c = tk.Canvas(root, height=1000, width=1000, bg='white')
c.pack(fill=tk.BOTH, expand=True)
c.bind('<Configure>', create_grid)
root.mainloop()
I am trying to animate arcs and circles. The circles are moving every frame. While the arcs are changing radius, position and disappearing as functions of the positions of the circles.
I am trying to animate these arcs , but they are not changing.
Below is the code sample:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import patches
import numpy as np
particle_one = np.zeros((10,2)) #10 times steps and x,y positions
particle_two = np.zeros((10,2)) #10 times steps and x,y positions
#the two particles are moving away from each other in the x direction
for i in range(0,10):
particle_one[i,0] = i
particle_two[i,0] = 2-i
particle_one[i,1] = 2
particle_two[i,1] = -2
particle_One_Radius = 1
particle_Two_Radius = 1.5
arc_Center = np.zeros((10,2))
for i in range(0,10):
arc_Center[i,0] = (particle_one[i,0] + particle_two[i,0])/2
#the arc should disappear for frame 5
arc_Center[5,0] = 0
arc_Center[5,1] = 0
fig = plt.figure()
plt.axis([-20,20, -5,5]) #axis that I like
ax = plt.gca()
circle_One = plt.Circle([particle_one[0,0],particle_one[0,1]],particle_One_Radius)
circle_Two = plt.Circle([particle_two[0,0],particle_two[0,1]],particle_Two_Radius)
circles = []
circles.append(circle_One)
circles.append(circle_Two)
arcs = []
#defines the arc
arc_one = patches.Arc([arc_Center[0,0],arc_Center[0,1]],5,3,angle =0 ,theta1 = 0,theta2= 270)
arcs.append(arc_one)
def init():
ax.add_patch(circles[0])
ax.add_patch(circles[1])
ax.add_patch(arcs[0])
return ax
#draw every frame by frame
def animate(m):
circles[0].center=((particle_one[m,0],particle_one[m,1]))
circles[1].center=((particle_two[m,0],particle_two[m,1]))
#the arcs does not change
arcs[0] =patches.Arc([arc_Center[m,0],arc_Center[m,1]],5+m,3+m,angle =0 ,theta1 = 0,theta2= 270)
return ax
#animation function that draws 10 frames
anim = animation.FuncAnimation(fig,animate , init_func= init , frames = 10 , interval = 20)
plt.show()
The circles animate correctly , but the arc does not change shape or location
Your problem is that instead of modifying your Arc patch as you do the circles, you create a new one at each step, but do not add it to the axes after it's created.
I've checked briefly, but I don't know how to modify the properties of an Arc instance, although I'm sure it's possible.
In the mean time, I've modified your function to remove the previous Arc from the patches list, create a new arc, and add it back to the Axes
#draw every frame by frame
def animate(m):
circles[0].center=((particle_one[m,0],particle_one[m,1]))
circles[1].center=((particle_two[m,0],particle_two[m,1]))
ax.patches.remove(arcs[0])
arcs[0] = patches.Arc([arc_Center[m,0],arc_Center[m,1]],5+m,3+m,angle =0 ,theta1 = 0,theta2= 270)
ax.add_patch(arcs[0])
print "step %d: arc = %s" % (m, arcs[0])
return circles,arcs
I have also ran into the problem of my arc not moving. Trying to remove the arc as Diziet suggested generated the
error: "x not in list".
However, what seems to work is to do both the instantiation of the arc and adding it to the axis within the animate function, but without the call to remove it - essentially, Diziet's solution minus the line "ax.patches.remove(arcs[0])".
I am rather new to matplotlib (and this is also my first question here). I'm trying to represent the scalp surface potential as recorded by an EEG. So far I have a two-dimensional figure of a sphere projection, which I generated using contourf, and pretty much boils down to an ordinary heat map.
Is there any way this can be done on half a sphere?, i.e. generating a 3D sphere with surface colours given by a list of values? Something like this, http://embal.gforge.inria.fr/img/inverse.jpg, but I have more than enough with just half a sphere.
I have seen a few related questions (for example, Matplotlib 3d colour plot - is it possible?), but they either don't really address my question or remain unanswered to date.
I have also spent the morning looking through countless examples. In most of what I've found, the colour at one particular point of a surface is indicative of its Z value, but I don't want that... I want to draw the surface, then specify the colours with the data I have.
You can use plot_trisurf and assign a custom field to the underlying ScalarMappable through set_array method.
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
(n, m) = (250, 250)
# Meshing a unit sphere according to n, m
theta = np.linspace(0, 2 * np.pi, num=n, endpoint=False)
phi = np.linspace(np.pi * (-0.5 + 1./(m+1)), np.pi*0.5, num=m, endpoint=False)
theta, phi = np.meshgrid(theta, phi)
theta, phi = theta.ravel(), phi.ravel()
theta = np.append(theta, [0.]) # Adding the north pole...
phi = np.append(phi, [np.pi*0.5])
mesh_x, mesh_y = ((np.pi*0.5 - phi)*np.cos(theta), (np.pi*0.5 - phi)*np.sin(theta))
triangles = mtri.Triangulation(mesh_x, mesh_y).triangles
x, y, z = np.cos(phi)*np.cos(theta), np.cos(phi)*np.sin(theta), np.sin(phi)
# Defining a custom color scalar field
vals = np.sin(6*phi) * np.sin(3*theta)
colors = np.mean(vals[triangles], axis=1)
# Plotting
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
cmap = plt.get_cmap('Blues')
triang = mtri.Triangulation(x, y, triangles)
collec = ax.plot_trisurf(triang, z, cmap=cmap, shade=False, linewidth=0.)
collec.set_array(colors)
collec.autoscale()
plt.show()