2017-06-10 6 views
0

I ont des particules en forme de tige souhaité en 2D qui sont constitués d'une partie rectangulaire du milieu de la longueur (l) et la largeur (d), il y a deux capuchons semi-circulaires sur les deux extrémités de diamètre (d). Diamètre (d) pour toutes les particules reste constante et la longueur (l) change. Je veux le visualiser en python. Matplotlib peut-il le faire avec des marqueurs personnalisés? Comme il y a environ 5K particules en simulation, je veux que ce soit rapide. J'ai utilisé gnuplot, en traçant les bâtonnets comme des vecteurs, ce qui me donne une idée des particules, mais pas la taille réelle.Visualisation des particules en forme de tige 2D en python

+0

Voulez-vous avoir la taille des particules dans les données coordonnées absolues ou seulement par rapport à l'autre? – ImportanceOfBeingErnest

+0

J'ai des coordonnées de données absolues, mais il y a une taille minimale avec laquelle je peux évoluer. –

Répondre

1

Vous voudrez peut-être regarder this post, qui utilise une idée de this answer.

Une tige serait une ligne avec des chapeaux sphériques (solid_capstyle="round").

enter image description here

La largeur de raie, qui est normalement donnée en points est alors calculée à partir des unités de données et les données en cours de transformation. Afin d'ajouter plusieurs de ces lignes, on peut changer le code de la publication mentionnée ci-dessus pour créer beaucoup de lignes. Malheureusement, un LineCollection, qui permettrait d'accélérer les choses, ne permet pas de changer le capstyle.

Voici un exemple:

import matplotlib.pyplot as plt 
from matplotlib.lines import Line2D 
import numpy as np 

class Rods(): 
    def __init__(self, x,y,l,w=1, angle=0, **kwargs): 
     self.ax = kwargs.pop("ax", plt.gca()) 
     self.color=kwargs.pop("color", "lightblue") 
     self.lw = 1 
     self.ax.figure.canvas.draw() 
     self.ppd=72./self.ax.figure.dpi 
     self.trans = self.ax.transData.transform 
     self.lines = [] 
     self.set_data(x,y,l,w, angle) 

     self.cid=self.ax.figure.canvas.mpl_connect('resize_event',self._resize) 
     self.cid1=self.ax.figure.canvas.mpl_connect("motion_notify_event",self._resize) 
     self.cid2=self.ax.figure.canvas.mpl_connect('button_release_event',self._resize) 

    def set_data(self, x,y,l,w=1, angle=0, color=None): 
     if color: self.color=color 
     self.lw_data = w 
     m = np.array([[np.cos(angle), -np.sin(angle)],[np.sin(angle), np.cos(angle)]]) 
     xy1 = np.dot(m, np.c_[np.zeros_like(x),-l/2.*np.ones_like(x)].T).T 
     xy2 = np.dot(m, np.c_[np.zeros_like(x), l/2.*np.ones_like(x)].T).T 

     x = np.c_[xy1[:,0] + x,xy2[:,0] + x] 
     y = np.c_[xy1[:,1] + y,xy2[:,1] + y] 

     if self.lines: 
      for line in self.lines: line.remove() 
     for i in range(len(x)): 
      line = Line2D(x[i,:], y[i,:], 
          solid_capstyle="round", color=self.color) 
      self.lines.append(line) 

     for line in self.lines: 
      self.ax.add_artist(line) 
     self._resize() 

    def _resize(self, event=None): 
     lw = ((self.trans((1,self.lw_data))-self.trans((0,0)))*self.ppd)[1] 
     if lw != self.lw: 
      for line in self.lines: 
       line.set_linewidth(lw) 
      self.ax.figure.canvas.draw_idle() 
      self.lw = lw 


fig, ax = plt.subplots() 
ax.set_aspect('equal') 
ax.axis([0,6,0,6]) 

x = np.array([1,2,3,4]) 
y = np.array([2,3,5,5]) 
l = np.array([2,3,5,4])*0.2 

r = Rods(x,y,l,w=0.1, angle=45, color="crimson") 
r = Rods(y[::-1],x[::-1],l,w=0.4, angle=90, color="purple") 

plt.show() 

enter image description here

+0

Cela devrait le faire. Je vous remercie. –