Center of a circle patch in Matplotlib - python

I have created an array of Circle patches in Matplotlib. I need to get a
list of the centers of these circle patches, for some computation.
On the documentation page of the circle patch (see matplotlib.patches.Circle on this page) , there don't seem to be any methods for extracting the center of the circle say as in mycircle.get_center. They have one for the radius, but not for the center. Any suggestions?
EDIT:
Here is some code. Basically, what I want to do is to create an interactive app in which the user clicks some disks with the mouse onto
the screen. The only constraint on positioning these disks, is that they
should all be disjoint. So when the user tries to insert a disk with a mouse click, I want to check if the new disk intersects the already inputted disks.
I am storing all the circle patches in an array called disk_arrangement.
Sure, I could create a separate array recording the centers, to do my job,
but that seems ugly. That's why I hope Matplotlib as a method to extract the center of a given circle-patch
def place_disk(event, disk_arrangement=[] ):
def is_inside_an_existing_disk(center_x, center_y):
if disk_arrangement != []:
for existing_disk in disk_arrangement:
if existing_disk.contains(event): #### How to do this????
return True
return False
if event.name == 'button_press_event' and \
event.dblclick == True and \
event.xdata != None and \
event.ydata != None and \
is_inside_an_existing_disk(event.xdata,event.ydata) == False :
cursor_circle = mpl.patches.Circle((event.xdata,
event.ydata),
radius=0.3,
facecolor= 'green')
disk_arrangement.append(cursor_circle)
ax.add_patch(cursor_circle)
fig.canvas.draw()
I am using Python 2.7.11 on Ubuntu 14.04

Try the center attribute, e.g. for a patch initialized with:
from matplotlib.patches import Circle
circ = Circle((1, 2), radius=1)
circ.center == (1,2) #should return True
To determine all the attributes of an object you can use dir, e.g. dir(circ) gives all attributes of the circ object including center, radius, etc.

Related

Vedo: Is there a way to add a camera to scenes and see images from perspective?

I'm using Vedo in Python to visualize some 3D scans of indoor locations.
I would like to, e.g., add a 'camera' at (0,0,0), look left 90 degrees (or where ever), and see the camera's output.
Can this be done with Vedo? If not, is there a different python programming framework where I can open .obj files and add a camera and view through it programmatically?
I usually use schema:
...
plt = Plotter(bg='bb', interactive=False)
camera = plt.camera
plt.show(actors, axes=4, viewup='y')
for i in range(360):
camera.Azimuth(1)
camera.Roll(-1)
plt.render()
...
plt.interactive().close()
Good Luck
You can plot the same object in an embedded renderer and control its behaviour via a simple callback function:
from vedo import *
settings.immediateRendering = False # can be faster for multi-renderers
# (0,0) is the bottom-left corner of the window, (1,1) the top-right
# the order in the list defines the priority when overlapping
custom_shape = [
dict(bottomleft=(0.00,0.00), topright=(1.00,1.00), bg='wheat', bg2='w' ),# ren0
dict(bottomleft=(0.01,0.01), topright=(0.15,0.30), bg='blue3', bg2='lb'),# ren1
]
plt = Plotter(shape=custom_shape, size=(1600,800), sharecam=False)
s = ParametricShape(0) # whatever object to be shown
plt.show(s, 'Renderer0', at=0)
plt.show(s, 'Renderer1', at=1)
def update(event):
cam = plt.renderers[1].GetActiveCamera() # vtkCamera of renderer1
cam.Azimuth(1) # add one degree in azimuth
plt.addCallback("Interaction", update)
interactive()
Check out a related example here.
Check out the vtkCamera object methods here.

How to draw a circular shape in PyBox2D

I have a code which draws a figure consisting of few polygon shapes using pyBox2D and PyGame. Ihave defined bodies and joints, it works well, it does what it is supposed to do, but problem occures when I want to change the head from polygon to circle shape, but I cannot draw it because I use for drawing vertices and circle shape has no vertices.
The problem occurs in this part of code (final drawing):
for body in world.bodies: #(ground_body, dynamic_body): # or: world.bodies
# The body gives us the position and angle of its shapes
for fixture in body.fixtures:
shape = fixture.shape
vertices = [(body.transform * v) * PPM for v in shape.vertices]
vertices = [(v[0], SCREEN_HEIGHT - v[1]) for v in vertices]
pygame.draw.polygon(screen, colors[body.type], vertices)
As I said above, the problem is that box2D. b2circleShape does not have vertices. How can i draw a circle or ad vertices to that shape?
Thank you very much
EDIT: The "duplicate" does not answer my question, could you please show me how to define circular body I tried this
import Box2D # The main library
# Box2D.b2 maps Box2D.b2Vec2 to vec2 (and so on)
from Box2D.b2 import (world, polygonShape, staticBody, dynamicBody, circleShape)
from Box2D import (b2FixtureDef, b2PolygonShape, b2CircleShape)
chest_body = world.CreateDynamicBody(
position=(10, 6.5),
fixtures=b2FixtureDef(
shape=b2PolygonShape(box=(0.5, 1.5)), density=120),
angle=0) # This is a rectangular body which is defined correctly
circle = world.CreateDynamicBody(
position=(10, 6.5),
fixtures=b2FixtureDef(
shape=b2CircleShape(0.5),
angle=0)) # I tried this after checking your manual, this does not work
The problem may be caused (and probably is caused) by the fact that i do not know how to run IntelliSense for pyBox2D or whether there is intellisense at all. That means that I do not know which parameters are needed
Any help appreciated
There is a manual for python too. Check this
circle = b2CircleShape(pos=(1, 2), radius=0.5)

maya python script - how to check the UV boundaries of models?

I'm looking for a python function or script which could check the borders of all uv shells in the scene, including exceeds the border or too close to the border.
The scripts I found are mainly used to find all uv shells in a selected object.
https://polycount.com/discussion/196753/maya-python-get-a-list-of-all-uv-shells-in-a-selected-object
But I want to check the borders of all uv shells, and if there are any errors in the scene, it could show me exactly the model that is irregular.
Thanks,
This is a very rudimentary example. It loops over all the meshes in the scene, collecting their UV bounding boxes using cmds.polyEvaluate. If it finds anything which sticks outside the bounding box supplied, it adds them to a list. It returns two things: first the uv bounds of the entire scene, second the list of items outside the target bounding box.
import maya.cmds as cmds
def scene_uv_bounds(target = (0,0,1,1)):
umin, vmin, umax, vmax = 0, 0, 0, 0
for item in cmds.ls(type='mesh'):
out_of_bounds = []
# polyEvaluate -b2 returns [(umin, umax) , (vmin, vmas)]
uvals, vvals = cmds.polyEvaluate(item, b2=True)
#unpack into separate values
uumin, uumax = uvals
vvmin, vvmax = vvals
if uumin < target[0] or vvmin < target[1] or uumax > target[2] or vvmax > target[3]:
out_of_bounds.append(item)
umin = min(umin, uumin)
umax = max(umax, uumax)
vmin = min(vmin, vvmin)
vmax = max(vmax, vvmax)
return (umin, vmin, umax, vmax), out_of_bounds
#usage
uv_bounds, out_of_bounds_meshes = scene_uv_bounds()
Depending on your content you might need to manage the active UV set on the different items, but for simple one-channel cases this catches most cases.

Mayavi Contour 3d

If I plot a 3d data using contour3d option of mayavi, there are 3 default contours but how they spaced. I understand the number of contours can be changed, but can they be at user specified values (I would surely guess that is possible). I would like to know how are the default 3 contours drawn. Depending on maximum value of scalar and how is it distributed.
As it happens I just had the same problem and found a solution.
Here is some sample code:
import numpy as np
from mayavi import mlab
from mayavi.api import Engine
def fun(x, y, z):
return np.cos(x) * np.cos(y) * np.cos(z)
# create engine and assign figure to it
engine = Engine()
engine.start()
fig = mlab.figure(figure=None, engine=engine)
contour3d = mlab.contour3d(x, y, z, fun, figure=fig)
scene = engine.scenes[0]
# get a handle for the plot
iso_surface = scene.children[0].children[0].children[0]
# the following line will print you everything that you can modify on that object
iso_surface.contour.print_traits()
# now let's modify the number of contours and the min/max
# you can also do these steps manually in the mayavi pipeline editor
iso_surface.compute_normals = False # without this only 1 contour will be displayed
iso_surface.contour.number_of_contours = 2
iso_surface.contour.minimum_contour = -1.3
iso_surface.contour.maximum_contour = 1.3
Now about the meaning of the contours. Well, the number obviously says how many contours are created. Then the values for min/max will define a linear space over which the contours will be spread. The value should basically influence the shrinkage/expansion along the surface normals.
Edit: Here's a tip. When you got your plot window, click on the mayavi pipeline icon in the top left. There you can modify your object (usually lowest in the tree). When you press the red record button and start modifying things it will give you the corresponding lines of code.

plot_surface : get the x,y,z values written in the bottom right corner

I am a quite new user of matplotlib. When plotting a surface (3D) with matplotlib and plot_surface, a window appears with the graph. In that windows, on the bottom right corner there is the coordinates of the actual position of the mouse. Is is possible to gain access to these values?
I have search on internet but very few solutions are proposed. For a 2D plot, these values are accessible using a tkinter.canvas but in 3D, when using the same technique the event.xdata and event.ydata did not return the good position for the mouse.
With ax.format_coord(mouseevent.xdata,mouseevent.ydata) you get the x, y, z values in a string ('x=0.222, y=0.452, z=0.826') from which you can extract the values.
For example for y-coordinate:
def gety(x,y):
s = ax.format_coord(x,y)
out = ""
for i in range(s.find('y')+2,s.find('z')-2):
out = out+s[i]
return float(out)
I tried #Thilo's answer and received only a single float. Using Python 3.8 and Matplotlib version 3.2.1.
Modified his function to this
def getxyz(event):
s = ax.format_coord(event.xdata, event.ydata)
out = [float(x.split('=')[1].strip()) for x in s.split(',')]
print(out)
return out
Many thanks, because without that answer I would never knew something like format_coord exist.

Categories