[Matplotlib-users] How to draw a collection of oriented triangles ?

Nicolas P. Rougier Nicolas.Rougier at inria.fr
Sun Nov 27 02:34:59 EST 2016


Thanks. I end up using a PathCollection with a single path. The advantage is that you can split a path into several disconnected paths but the update can still be made at once (scaling, translating and rotation). This makes things relatively fast.

Code is available at: https://gist.github.com/rougier/b82fe08f1840f4277b52fb8bfbdb3cc7



Nicolas


> On 26 Nov 2016, at 21:47, Joshua Klein <mobiusklein at gmail.com> wrote:
> 
> I don’t think my code ever directly works with a PatchCollection object, just individual patches which possess distinct properties. Here’s an example using animations:
> 
> import
>  matplotlib
> matplotlib.use(
> "Tkagg"
> )
> 
> from matplotlib import pyplot as
>  plt
> 
> from matplotlib.path import
>  Path
> 
> from matplotlib.transforms import
>  Affine2D
> 
> from matplotlib.patches import
>  PathPatch
> 
> from matplotlib import
>  animation
> 
> import numpy as
>  np
> 
> unit_triangle = Path.unit_regular_polygon(
> 3
> )
> 
> 
> def make_triangle(x, y, rot_deg, color, scale):
> 
>     path = Path(unit_triangle.vertices * scale, unit_triangle.codes)
>     trans = Affine2D().translate(x, y).rotate_deg_around(x, y, rot_deg)
>     t_path = path.transformed(trans)
>     patch = PathPatch(t_path, facecolor=color)  
>     
> return
>  patch
> 
> triangles = [(
> 1, 1, 90), (2, 2, 45), (-1, 1, 128
> )]
> patches = []
> 
> 
> def step_fn(i):
> 
>     next_step = []
>     
> # Random walk update each triangle's position
> 
>     
> for tri in
>  triangles:
>         x = tri[
> 0] + np.random.random() - 0.5
> 
>         y = tri[
> 1] + np.random.random() - 0.5
> 
>         rot = tri[
> 2] + (np.random.random() - 0.5) * 45
> 
>         next_step.append((x, y, rot))
>     triangles[:] = next_step
> 
>     
> # Remove the old patches
> 
>     
> while
>  patches:
>         patch = patches.pop()
>         patch.remove()
> 
>     
> # Add the new patches
> 
>     patches[:] = [make_triangle(x, y, rot_deg, 
> "blue", 0.2) for x, y, rot_deg in
>  triangles]
>     
> for patch in
>  patches:
>         plt.gca().add_patch(patch)
>     plt.autoscale()
> 
> fig = plt.figure()
> a = animation.FuncAnimation(fig, step_fn, blit=
> False, interval=10
> )
> 
> plt.show()
> 
> 
> On Sat, Nov 26, 2016 at 12:20 PM, Nicolas P. Rougier <Nicolas.Rougier at inria.fr> wrote:
> 
> Thank you Joshua, I'll start from your code. My other problem is that I also need to update rotation and position (for an animation). Hope this will work with patch collection and updating individual transform.
> 
> Nicolas
> 
> > On 26 Nov 2016, at 15:53, Joshua Klein <mobiusklein at gmail.com> wrote:
> >
> > I’ve had great success using PathPatch and AffineTransform for this purpose:
> >
> > from matplotlib import pyplot as
> >  plt
> >
> > from matplotlib.path import
> >  Path
> >
> > from matplotlib.transforms import
> >  Affine2D
> >
> > from matplotlib.patches import
> >  PathPatch
> >
> > unit_triangle = Path.unit_regular_polygon(
> > 3
> > )
> >
> >
> > def make_triangle(x, y, rot_deg, color, scale):
> >
> >     path = Path(unit_triangle.vertices * scale, unit_triangle.codes)
> >     trans = Affine2D().translate(x, y).rotate_deg_around(x, y, rot_deg)
> >     t_path = path.transformed(trans)
> >     patch = PathPatch(t_path, facecolor=color)
> >
> > return
> >  patch
> >
> > ax = plt.gca()
> >
> >
> > for x, y, rot_deg in [(1, 1, 90), (2, 2, 45), (-1, 1, 128
> > )]:
> >     patch = make_triangle(x, y, rot_deg,
> > "blue", 1
> > )
> >     ax.add_patch(patch)
> >
> >
> > # Patches don't automatically change the visible range of the axes like scatter does.
> >
> > ax.autoscale()
> >
> >
> > On Sat, Nov 26, 2016 at 9:21 AM, Nicolas P. Rougier <Nicolas.Rougier at inria.fr> wrote:
> >
> > I would like to draw several triangles (same size, same color) with different individual orientations.
> > Scatter plot does not allow to specify individual orientations and I've a hard time with PatchCollection.
> >
> > What would be the easiest way ? Is there an example somewhere around by any chance ?
> >
> >
> > Nicolas
> > _______________________________________________
> > Matplotlib-users mailing list
> > Matplotlib-users at python.org
> > https://mail.python.org/mailman/listinfo/matplotlib-users
> >
> 
> 



More information about the Matplotlib-users mailing list