2014-11-02 17 views
13

Quando si tratta di sovrapposizione di diagrammi di dispersione o linea ad alta densità di colori diversi, può essere conveniente implementare schemi di miscelazione additivi, in cui i colori RGB di ciascun marcatore si sommano per produrre il colore finale nella tela. Questa è un'operazione comune nei motori di rendering 2D e 3D.È possibile eseguire la miscelazione additiva con matplotlib?

Tuttavia, in Matplotlib ho trovato solo il supporto per il blending alpha/opacity. C'è qualche modo per farlo o sono bloccato con il rendering in bitmap e poi li unisco in un programma di disegno?

Modifica: ecco alcuni esempi di codice e una soluzione manuale.

Ciò produrrà due parzialmente sovrapposte distribuzioni casuali:

x1 = randn(1000) 
y1 = randn(1000) 
x2 = randn(1000) * 5 
y2 = randn(1000) 
scatter(x1,y1,c='b',edgecolors='none') 
scatter(x2,y2,c='r',edgecolors='none') 

Ciò produrrà in matplotlib seguente: scatter - no blend

Come si può vedere, ci sono alcuni punti blu sovrapposti che sono occluse da punti rossi e vorremmo vederli. Utilizzando alpha/opacità miscelazione in matplotlib, si può fare:

scatter(x1,y1,c='b',edgecolors='none',alpha=0.5) 
scatter(x2,y2,c='r',edgecolors='none',alpha=0.5) 

che produrrà i seguenti:

scatter - alpha blend (0.5)

Ma quello che voglio veramente è la seguente:

scatter - additive blend

Posso farlo manualmente rendendo ogni grafico indipendentemente da una bitmap:

xlim = plt.xlim() 
ylim = plt.ylim() 
scatter(x1,y1,c='b',edgecolors='none') 
plt.xlim(xlim) 
plt.ylim(ylim) 
scatter(x2,y2,c='r',edgecolors='none') 
plt.xlim(xlim) 
plt.ylim(ylim) 
plt.savefig(r'scatter_blue.png',transparent=True) 
plt.savefig(r'scatter_red.png',transparent=True) 

che mi dà le seguenti immagini:

scatter - red/blue channels

Che cosa si può fare è quindi caricarli come strati indipendenti in Paint.NET/PhotoShop/gimp e semplicemente additivo si fondono.

Ora l'ideale sarebbe essere in grado di farlo a livello di codice in Matplotlib, poiché ne elaborerò centinaia!

+0

Il modo più semplice è quello di creare un istogramma 2-D. Si prega di mostrarci alcuni esempi di codice e dati per iniziare. –

+0

Grazie, ho appena aggiunto qualche codice di esempio e i passaggi per una soluzione manuale. – glopes

+0

Grazie, molto meglio la domanda ora, vedrò cosa posso fare. –

risposta

7

Se avete solo bisogno di un'immagine come risultato, è possibile ottenere il buffer di tela come una matrice NumPy, e poi fare la fusione, ecco un esempio:

from matplotlib import pyplot as plt 
import numpy as np 

fig, ax = plt.subplots() 
ax.scatter(x1,y1,c='b',edgecolors='none') 
ax.set_xlim(-4, 4) 
ax.set_ylim(-4, 4) 
ax.patch.set_facecolor("none") 
ax.patch.set_edgecolor("none") 
fig.canvas.draw() 

w, h = fig.canvas.get_width_height() 
img = np.frombuffer(fig.canvas.buffer_rgba(), np.uint8).reshape(h, w, -1).copy() 

ax.clear() 
ax.scatter(x2,y2,c='r',edgecolors='none') 
ax.set_xlim(-4, 4) 
ax.set_ylim(-4, 4) 
ax.patch.set_facecolor("none") 
ax.patch.set_edgecolor("none") 
fig.canvas.draw() 

img2 = np.frombuffer(fig.canvas.buffer_rgba(), np.uint8).reshape(h, w, -1).copy() 

img[img[:, :, -1] == 0] = 0 
img2[img2[:, :, -1] == 0] = 0 

fig.clf() 

plt.imshow(np.maximum(img, img2)) 
plt.subplots_adjust(0, 0, 1, 1) 
plt.axis("off") 
plt.show() 

il risultato:

enter image description here

+0

Stavo proprio controllando le funzioni buffer_rgba() quando è arrivata la tua risposta. Sì, penso che questo sia il meglio che si possa fare con Matplotlib per ora. Per qualche ragione nella mia versione di Matplotlib il risultato finale non è così bello (la trasparenza è rovinata), ma sono sicuro che con un piccolo ritocco lo farò funzionare ora. Grazie! – glopes

Problemi correlati