2014-11-02 25 views
13

W przypadku nakładających się wykresów rozproszenia o wysokiej gęstości lub linii o różnych kolorach wygodne może być stosowanie schematów mieszania dodatków, w których kolory RGB każdego markera sumują się, tworząc ostateczny kolor w obszarze roboczym. Jest to typowa operacja w silnikach renderowania 2D i 3D.Czy możliwe jest mieszanie dodatków z matplotlib?

Jednak w Matplotlib znalazłem tylko obsługę mieszania alfa/nieprzezroczystości. Czy jest jakiś okrężny sposób robienia tego albo czy utknąłem z renderowaniem do bitmapy, a następnie mieszałem je w jakimś programie do malowania?

Edytuj: Oto przykładowy kod i rozwiązanie ręczne.

To będzie produkować dwa częściowo pokrywające się losowych rozkładów:

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') 

To będzie produkować w matplotlib następujące: scatter - no blend

Jak widać, istnieje kilka nakładających się niebieskie punkty, które są zamknięte przez czerwone punkty i chcielibyśmy je zobaczyć. Za pomocą alfa/krycie mieszania w matplotlib można zrobić:

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

która będzie produkować co następuje:

scatter - alpha blend (0.5)

Ale to, co naprawdę chcę to:

scatter - additive blend

Mogę to zrobić ręcznie, renderując każdy dział niezależnie do bitmapy:

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) 

Który daje mi następujące obrazy:

scatter - red/blue channels

Co można zrobić potem to załadować je jako niezależne warstwy w Paint.NET/PhotoShop/gimp i dodatku tylko zmieszać je.

Idealnie byłoby móc to zrobić programowo w Matplotlib, ponieważ będę przetwarzał ich setki!

+0

Najprostszym może być wykonanie 2-D histogramu. Pokaż nam przykładowy kod i dane, abyśmy mogli zacząć. –

+0

Dzięki, po prostu dodano przykładowy kod i kroki do ręcznego rozwiązania. – glopes

+0

Dzięki, o wiele lepsze pytanie, zobaczę, co mogę zrobić. –

Odpowiedz

7

Jeśli potrzebujesz tylko obraz jako wynik można uzyskać bufor płótno jako numpy tablicy, a następnie wykonaj mieszanie, oto przykład:

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() 

wynik:

enter image description here

+0

Właśnie sprawdzałem funkcje buffer_rgba(), gdy pojawiła się twoja odpowiedź. Tak, myślę, że jest to najlepsze, co można teraz zrobić z Matplotlibem. Z jakiegoś powodu w mojej wersji Matplotlib efekt końcowy nie jest tak ładny (przezroczystość jest zepsuta), ale jestem pewna, że ​​przy odrobinie ulepszenia sprawię, że zadziała teraz. Dzięki! – glopes

Powiązane problemy