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
Répondre
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"
).
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()
Cela devrait le faire. Je vous remercie. –
Voulez-vous avoir la taille des particules dans les données coordonnées absolues ou seulement par rapport à l'autre? – ImportanceOfBeingErnest
J'ai des coordonnées de données absolues, mais il y a une taille minimale avec laquelle je peux évoluer. –