I have a set of data, where each value has a (x, y) coordinate. Different values can have the same coordinate. And I want to draw them in a rectangular collection of boxes.
For example, if I have the data:
A -> (0, 0)
B -> (0, 1)
C -> (1, 2)
D -> (0, 1)
I want to get the following drawing:
0 1 2
+++++++++++++
0 + A + B + +
+ + D + +
+++++++++++++
1 + + + C +
+++++++++++++
2 + + + +
+++++++++++++
How can I do it in Python using Matplotlib?
THANKS!
Just thought, maybe what you actually wanted to know was just this:
def drawbox(list,x,y):
# write some graphics code to draw box index x,y containing items 'list'
[[drawbox(u,x,y) for u in X.keys() if X[u]==(y,x)] for x in range(0,3) for y in range(0,3)]
# enter the data like this
X={'A':(0,0),'B':(0,1),'C':(1,2),'D':(0,1)}
# size of grid
xi=map(tuple.__getitem__,X.values(),[1]*len(X))
yi=map(tuple.__getitem__,X.values(),[0]*len(X))
xrng = (min(xi), max(xi)+1)
yrng = (min(yi), max(yi)+1)
for y in range(*yrng): # rows
print '+' * ((xrng[1]-xrng[0])*3) + '+'
k={} # each item k[x] is list of elements in xth box in this row
for x in range(*xrng):
# list of items in this cell
k[x]=[u for u in X.keys() if X[u]==(y,x)]
h=max(map(len, k.values())) # row height
for v in range(h): # lines of row
c=[]
for x in range(*xrng): # columns
if k[x]:
c.append(k[x][0])
del k[x][0]
else: c.append(' ') # shorter cell
s="+ " + "+ ".join(c) + "+"
print s
print "+" * ((xrng[1]-xrng[0])*3) + '+'
Perhaps it would be better to use the ReportLab.
Example
Related
This question already has answers here:
Why doesn't calling a string method (such as .replace or .strip) modify (mutate) the string?
(3 answers)
Closed 4 years ago.
You can see in my code below that I am creating a list of strings that essentially forms as many circles defined by the planes list. The issue is associated with the hover list. Essentially, if click_x and click_y are within a certain region defined by the strings then it should replace all the strings within that region but for some reason text.replace(...) isn't doing anything and by that I mean after "replacing", the hover list is still the same. All help is appreciated.
Also I can't use np.where since I get a TypeError for some reason.
import numpy as np
planes = [2, 3, 4, 5]
edge = planes[-1]
x = np.linspace(-edge, edge, 50)
y = np.linspace(-edge, edge, 50)
regions = []
hover = []
# Normal Display
for i in x:
row = []
text_row = []
for j in y:
# TODO: Make what_region function
if np.sqrt(i ** 2 + j ** 2) < planes[0]:
row.append(7) # <- Arbitrary number to adjust color
text_row.append('Region 1')
if np.sqrt(i ** 2 + j ** 2) > planes[-1]:
row.append(5) # <- Arbitrary number to adjust color
text_row.append('Region {}'.format(len(planes) + 1))
for k in range(len(planes) - 1):
if planes[k] < np.sqrt(i ** 2 + j ** 2) < planes[k + 1]:
row.append(k * 3) # <- Arbitrary number to adjust color
text_row.append('Region {}'.format(k + 2))
regions.append(row)
hover.append(text_row)
# indices = np.where(np.array(hover) == "Region 1")
# for a in range(len(indices[0])):
# hover[indices[0][a]][indices[1][a]] = ("New Region")
click_x = np.random.uniform(-planes[-1], planes[-1])
click_y = np.random.uniform(-planes[-1], planes[-1])
# Change graph on Click TODO: Not filling region correctly (MUST FIX)
if np.sqrt(click_x ** 2 + click_y ** 2) < planes[0]:
print('1', True)
for row_ in hover:
for text in row_:
print(text)
text.replace('Region 1', 'New Region')
if np.sqrt(click_x ** 2 + click_y ** 2) > planes[-1]:
print('2', True)
for row_ in hover:
for text in row_:
print(text)
text.replace('Region {}'.format(len(planes)+1), 'Newer Region')
for k in range(len(planes) - 1):
if planes[k] < np.sqrt(click_x ** 2 + click_y ** 2) < planes[k + 1]:
print('3', True)
for row_ in hover:
for text in row_:
print(text)
text.replace('Region {}'.format(k+2), 'Newest Region')
print(hover)
Strings in python are immutable. This means that they cannot ever be edited, only replaced.
x = "silly sam"
x.replace("silly", "smart")
x is still "silly sam" because the replaced version of the string was not assigned to a variable and therefore discarded.
x = "silly sam"
x = x.replace("silly", "smart")
Now x has the value "smart"
Not sure about the syntax of the output I am receving. Any help would be appreciated.
Here is my code:
import numpy
def g(): #generate random complex values
return numpy.random.random(1) + numpy.random.random(1) *1j
p = numpy.poly1d(numpy.squeeze([g(),g(),g()])) # test function p
pprime = numpy.polyder(p) #derivative of p
print 'Our p(x) is {} '. format(p)
print('\n') # new line
print'Our pprime(x) is {} '. format(pprime) #apply newtons method to p
print('\n') # new line
#apply newtons method to p
def root_newton ( f, df, tolerance = 1.0e-6):
dx = 2 * tolerance
x=0
while dx > tolerance:
x1 = x - f(x)/df(x)
dx = abs (x - x1)
x = x1
return x
print('Our first root is at {}'.format(root_newton(p,pprime)))
print('\n') # new line
Here's the output:
Our p(x) is 2
(0.6957 + 0.683j) x + (0.3198 + 0.5655j) x + (0.9578 + 0.1899j)
Our pprime(x) is
(1.391 + 1.366j) x + (0.3198 + 0.5655j)
Our first root is at (0.00925817978737+0.830966156841j)
The correct roots are [-0.64968928-1.01513333j 0.00925818+0.83096616j]
What does the 2 above the second component in my first line outputted mean? I can't find anything similar to my question online. I am guessing it may mean the x component is squared but I'm not sure? This is python 3 by the way.
The 2 is the exponent on the first x, misaligned because you put text before it on the same line.
If we take your output:
Our p(x) is 2
(0.6957 + 0.683j) x + (0.3198 + 0.5655j) x + (0.9578 + 0.1899j)
and remove the text you prepended:
2
(0.6957 + 0.683j) x + (0.3198 + 0.5655j) x + (0.9578 + 0.1899j)
the intended meaning of the 2 becomes clearer.
Imagine that we have a w by h grid, where the tiles are numbered starting at 1 in the top left corner. w (for width) and h (for height) have been stored in a function. You have access to these stored values, as long as you call them w and h. Write a program to return: The column number of a tile number given by the user. Start counting columns at column 1.
import subprocess
def template(w, h, t):
#w and h are memory locations that already contain values
tile = t
sum = ((t - 1) // w) + 1
#END OF YOUR CODE
failed = 0
width = 1
while width <= 3:
height = 1
while height <= 3:
tile = 1
while tile <= width * height:
result = template(width, height, tile)
col = (tile - 1) % width + 1
if (result == col):
print "On a " + str(width) + " by " + str(height) +" board, with tile " + str(tile) +", col is " + str(col) + ", you got it RIGHT!"
else:
print "On a " + str(width) + " by " +:str(height)%+" board, with tile " + str(tile)%+", col is " + str(col) + ", you got: " + str(result)
failed = 1
tile += 1
height += 1
width += 1
if (failed == 0):
print "Your code is CORRECT!"
print "Please check your code, at least one test case did not pass."
I am almost there I think, but this formula isn't quite right and I'm out of ideas.
See below pseudo code, this approach should work for you,
# divide t by h, the tile should reside in the next row
tileRow = (t/h)+1
# get the reminder of the division, that's the column number
tileColumn = t%h
see the sample code I tried below
>>> w = 5
>>> h = 10
>>> t =36
>>> tileRow = (t/h)+1
>>> tileRow
4 # the tile is in the 4th row
>>> tileColumn = t%h
>>> tileColumn
6 # the tile is in the 6th column
>>>
You may also have to check if the tile number is within in range, in the above example its w x h (50)
Please comment if you need anymore clarification. If this resolves your problem you may accept and vote the answer
To create the grid, use a list comprehension.
grid=[list(range(x,x+w))for x in range(1,w*h,w)]
To find the column number of t, find the remainder of t divided by w:
t%w
So the function would be:
def template(w,h,t):
grid=[list(range(x,x+w))for x in range(1,w*h,w)]
return t%w
Example:
template(6,5,22)
Output:
4
I want to apply the following function to multiple instances of a, b, c but it seems I can't apply this function to a list. The goal is to compute a few inequalities and finally plug them into a new z = ax + bx equation in order to find the lowest or highest ordered pair.
This is a cleaner code that omits the use of lists:
xMin,yMin = 0,0
a,b,c = 2,-3,12
enter code here
def FindVar(object):
x = (-b*yMin)/a + c/a
y = (-a*xMin)/b + c/b
print '(', FindVar.x, ',', yMin, ')'
print '(', xMin, ',', FindVar.y, ')'
This is a longer code that uses lists a bit more sloppily:
xMin = 0
yMin = 0
def i1():
a,b,c = 2,-3,12
#Create and append l1
global l1
l1 = []
l1.extend((a,b,c))
#Find X,Y
y = (-a*xMin)/b + (c/b)
x = (-b*yMin)/a + c/a
#Add to list
pair = []
pair.append((xMin,y))
pair.append((x,yMin))
print '%sx + %sy = %s' % (a,b,c)
print 'RETURNS'
print pair[0], z1
print pair[1], z2
def i2():
a,b,c = 1,1,5
#Create and append l2
global l2
l2 = []
l2.extend((a,b,c))
#Find X,Y
y = (-a*xMin)/b + c/b
x = (-b*yMin)/a + c/a
#Add to list
pair = []
pair.append((xMin,y))
pair.append((x,yMin))
print '%sx + %sy = %s' % (a,b,c)
print 'RETURNS'
print pair[0], z1
print pair[1], z2
So with the second bit of code I end up with 4 list items, each of which should be applied to a final equation, z = ax + by where a and b are independent from other functions.
EDIT: The purpose is to take an equation like "z = 2x + 7y" and subject it to the rules:
2x - 3y ≤ 12,
x + y ≤ 5,
3x + 4y ≥ 24,
x ≥ 0,
y ≥ 0.
I take these equations and put them into a list so that a,b,c = [2,-3,12],[1,1,5],[3,4,24] (where a = 2,1,3, b = -3,1,4, and c = 12,5,24). Then I can find (x,y) according to each of the three instances and plug each of those ordered pairs into my initial "z = 2x + 7y". The point of all of this is to take sets of data and find which set is the most efficient.
z1 and z2 were used in a prior version of the code to apply the "z=2x+7y" to the first and second ordered pairs of the first equation.
EDIT 2:
This is the much cleaner code I came up with.
xMin = 0
yMin = 0
a = [10,11,1]
b = [7,-8,1]
c = [200,63,42]
def findxy(a,b,c):
#Finds x,y for ax+by=c
x = (-b*yMin)/a + c/a
y = (-a*xMin)/b + c/b
#The results, followed by the z function "z = 15x + 15y"
if x >= xMin:
print '(%s, %s)' % (x,yMin), 15 * x + 15 * yMin
if y >= yMin:
print '(%s, %s)' % (xMin,y), 15 * xMin + 15 * y
map(findxy,a,b,c)
Results in
(20, 0) 300
(0, 28) 420
(5, 0) 75
(42, 0) 630
(0, 42) 630
Thanks!
To apply a function to each object in a list you can use the built in function map.
The list you pass to map can consist of primitives, class instances, tuples or lists.
I am writing a simple command line program in Python 3.3 which reads a text file of xyz-coordinates and outputs a the equivalent triangle faces in between. The export format are Wavefront obj-files (https://en.wikipedia.org/wiki/Wavefront_.obj_file). The algorthm is solely intended to work with regular spaced points from high resolution satellite scans of the earth. Actually, I am using a set of about 340000 points and creating 2 triangles in between a vertex quadrupel. The outer iteration goes in x-direction while the inner iteration is over the y-direction. So, pairs of triangle faces are creates for every vertex in y-direction until it moves on in x-direction and repeats the process. I will show you the principle pattern (the lines are the face edges):
v1--v5--v9
| \ | / |
v2--v6--v10
| / | \ |
v3--v7--v11
| \ | / |
v4--v8--v12
The code seems to work in way as importing the file in Blender or MeshLab gives reasonable results, except for one thing: All stripes of face pairs seem to be not connected with their neighbors along the x-axis. A rendered picture which demonstrates the problem:
unconnected stripes.
Normally, there shouldn't be an vertical offset between different face-stripes because they share the same vertices along their interior border(-line). Tests with less vertices and more common low coordinate values succeeded. The method was working perfectly fine. Maybe the problem lies not within my mesh generator but within the coordinate limitations of Blender, MeshLab, etcetera.
Here is the function which generates the faces and stitches everythin together in an return-string:
def simpleTriangMesh(verts):
printAll("--creating simple triangulated mesh", "\n")
maxCoords = [max(verts[0]), max(verts[1]), max(verts[2])]
minCoords = [min(verts[0]), min(verts[1]), min(verts[2])]
printAll("max. coordinates (xyz): \n", maxCoords, "\n")
printAll("min. coordinates (xyz): \n", minCoords, "\n")
xVerts = 0 # amount of vertices in x-direction
yVerts = 0 # amount of vertices in y-direction
faceAmount = 0 # amount of required faces to skin grid
i = 0
temp = verts[0][0]
while(i < len(verts[0])):
if(temp < verts[0][i]):
yVerts = int(i)
break
temp = verts[0][i]
i += 1
xVerts = int(len(verts[0]) / float(yVerts))
faceAmount = ((xVerts - 1) * (yVerts - 1)) * 2
printAll("vertices in x direction: ", xVerts, "\n")
printAll("vertices in y direction: ", yVerts, "\n")
printAll("estimated amount of triangle faces: ",
faceAmount, "\n")
printAll("----generating vertex triangles representing the faces", "\n")
# list of vertex-index quadrupels representing the faces
faceList = [[0 for line in range(0, 3)] for face in range(0, int(faceAmount))]
f = 0
v = 0
# rather to draw hypotenuse of the triangles from topleft to bottomright
# or perpendicular to that (topright to bottomleft)
tl = True # the one that changes in y-direction
tl_rem = False # to remember the hypotenuse direction of the last topmost faces
while(f < len(faceList)):
# prevent creation of faces at the bottom line
# + guarantees that v = 1 when creating the first face
if(( v % yVerts ) == 0):
v += 1
tl = not tl_rem
tl_rem = tl
if(tl):
faceList[f][0] = v
faceList[f][1] = v + yVerts
faceList[f][2] = v + yVerts + 1
f += 1
faceList[f][0] = v
faceList[f][1] = v + yVerts + 1
faceList[f][2] = v + 1
else:
faceList[f][0] = v
faceList[f][1] = v + yVerts
faceList[f][2] = v + 1
f += 1
faceList[f][0] = v + 1
faceList[f][1] = v + yVerts
faceList[f][2] = v + yVerts + 1
f += 1
v += 1
tl = not tl
printAll("----preparing obj-file-content for export", "\n")
rectMesh_Obj = "" # string containing the mesh in obj-format (ascii)
tempVerts = ""
tempFaces = ""
row = 0
while(row < len(verts[0])):
# temp = ("v" + " " + str(verts[0][row]) + " " + str(verts[1][row])
# + " " + str(verts[2][row]) + "\n")
temp = ("v" + " " + str(verts[0][row]) + " " + str(verts[2][row])
+ " " + str(verts[1][row]) + "\n")
tempVerts += temp
row += 1
row = 0
while(row < len(faceList)):
temp = ("f"
+ " " + str(int(faceList[row][0]))
+ " " + str(int(faceList[row][1]))
+ " " + str(int(faceList[row][2]))
# + " " + str(int(faceList[row][3]))
+ "\n")
tempFaces += temp
row += 1
rectMesh_Obj += tempVerts + tempFaces
return(rectMesh_Obj)
The verts-variable which is inputted into the function has the form of a 2-dimensional list, similar to:
# x y z
vertsExample = [[3334, 3333, 3332], [2555, 2554, 2553], [10.2, 5.2, 6.7]]
I hope some of you can help me out of the misery. If something requires more explanation, please let me know and I will add it to the first post.
I finally solved the issue. The problem wasn't in my mesh generator program. Blender and MeshLab (and most likely other 3D-Programs as well) do some weird things when the coordinates of vertices are too big. If am reducing the real world geographically projected coordinates to smaller relative coordinates everything works just fine (https://dl.dropboxusercontent.com/u/13547611/meshGenWorking001.png).
My guess:
The Wavefront obj-format has too limited byte-sizes for its numbers. or to be more correct: Common 3D-Programs do not expect the numbers to be so big like the real world ones. This way they interpret what they get in a confusing manner.
I hope this solution helps somebody in the future !