2015-05-06 90 views
12

Tôi đang âm mưu một loạt các dữ liệu trên một logscale như một biểu đồ phân tán trong matplotlib (chỉ trong trường hợp các phương tiện có liên quan) sử dụng màu RGBA. Những gì tôi muốn để có thể làm là một khi tôi vẽ tất cả mọi thứ, tôi muốn chọn ra điểm phân tán cá nhân và thay đổi màu sắc của họ để màu sắc của một số màu RGB, nhưng bảo quản giá trị alpha cũ. Con đường tôi đang làm điều đó là thế này:Thay đổi màu sắc của rgba màu

oldHSV = rgb_to_hsv(oldRGBA[:3]) 
newHSV = rgb_to_hsv(newRGB) 
oldHSV[0] = newHSV[0] 
newRGBA = hsv_to_rgb(oldHSV).tolist() + [oldRGBA[3]] 

tức là tôi lấy một phần RGB giá trị RGBA cũ, biến nó để HSV, làm tương tự cho các màu RGB dự định mới, sau đó thay thế các màu sắc, biến nó quay lại RGB và thêm vào giá trị alpha cũ.

Kể từ khi tôi đang làm hàng ngàn này lần, điều này có thể mất nhiều thời gian hơn nhiều so với tôi muốn chi tiêu ở đây. Một sửa chữa có thể là đào sâu vào chuyển đổi giữa RGB và HSV và tìm ra cách để làm điều này trong một lần, nhưng tôi hy vọng rằng những người biết cách xử lý màu (tôi thực sự không) đã tìm ra đơn giản và hiệu quả cách để làm điều này.

Làm thế nào để thay đổi màu sắc của một trao RGBA màu A đến của một trao RGB màu B trong khi vẫn giữ giá trị alpha của A? Việc sử dụng một mô hình màu khác (ví dụ HSL) sẽ đơn giản hóa tác vụ và nếu có, điều đó sẽ giúp ích gì?

Trả lời

5

Dưới đây là giải pháp để làm tất cả việc thay thế chỉ trong một bước:

import matplotlib.colors as clr 
import matplotlib.pyplot as plt 
import numpy as np 


N = 100000 
x = 1.2 + 800.0 * np.random.rand(N) 
y = 1.2 + 800.0 * np.random.rand(N) 
# Generate random colors of the form (r, g, b, a) where r = 0.0 
colors = np.random.rand(4 * N).reshape((N, 4)) 
colors[:, 0] = 0.0 
area = np.pi * (5 * np.random.rand(N))**2 

fig = plt.figure() 
ax = fig.add_subplot(1, 1, 1) 
pcol = ax.scatter(x, y, s=area, c=colors) 
ax.set_xscale('log') 
ax.set_yscale('log') 

# Save initial figure 
plt.savefig("hue.jpg") 

oldRGBA = pcol.get_facecolors().reshape((N, 1, 4)) 
oldRGB = oldRGBA[:, :, :3] 
newRGB = oldRGB 
newRGB[:, :, 0] = 1.0 # Set red component to 1.0 
oldHSV = clr.rgb_to_hsv(oldRGB) 
newHSV = clr.rgb_to_hsv(newRGB) 
oldHSV[:, :, 0] = newHSV[:, :, 0] 
newRGBA = np.copy(oldRGBA) 
newRGBA[:, :, :3] = clr.rgb_to_hsv(oldHSV) 
pcol.set_facecolors(newRGBA[:, 0, :]) 

# Save modified figure 
plt.savefig("hue_bis.jpg") 

plt.close() 

Như bạn thấy, đoạn mã này cố gắng vẽ 100000 điểm và trên thực tế nó được quản lý để làm điều này trong khoảng 2 giây. Dưới đây là những con số được sản xuất:

hue.jpg

và:

hue_bis.jpg

liên quan đến hai câu hỏi cuối cùng của bạn Với:

Làm thế nào để thay đổi màu sắc của một RGBA cho màu A với màu RGB B đã cho trong khi vẫn giữ giá trị alpha của A?

và:

sẽ sử dụng một mô hình màu khác nhau (HSL ví dụ) đơn giản hóa các nhiệm vụ, và nếu như vậy, mà sẽ giúp

Tôi nghĩ rằng cách tiếp cận của bạn để làm như vậy sửa đổi là đáng kể, nó tránh thực hiện các phép tính bằng tay (xem HSL and HSV). Sử dụng một mô hình màu khác nhau là có thể, cả HSL và HSV cho phép thay đổi màu sắc mà không ảnh hưởng đến các thông số khác, nhưng đó chỉ là một cách khác để làm điều đó và không phải là một tốt hơn.

Hy vọng điều này sẽ hữu ích.

+1

Hay đấy; trong khi không dẫn đến một cách để cải thiện hiệu suất của mã của tôi, nó đã cho tôi một quan điểm để xem mã của người khác sẽ đi về nó như thế nào (và mã của tôi không chậm hơn). –

+0

Ồ! Tôi mong đợi hiệu suất tốt hơn trong một lần. Tôi sẽ xem xét nó gần hơn một chút. Bạn có một đoạn mã làm việc thực hiện giải pháp của bạn và cho phép bản thân tôi tiết kiệm thời gian không? – Flabetvibes

+0

Thật không may là tôi không; mã của tôi nằm trong một công cụ trực quan hóa dữ liệu và tôi nghĩ rằng việc thay đổi màu sắc có thể là nút cổ chai trong một trong các hoạt động tôi áp dụng cho hình ảnh hóa. Tôi không thể thực sự giải nén nó, nó không được viết đủ thanh lịch cho điều đó. Nhưng trên thực tế, câu trả lời của bạn về cơ bản đã trả lời được vấn đề của tôi: đây có thực sự là một nút cổ chai và tôi có thể xử lý nội dung nhanh hơn không? Hóa ra, rõ ràng là không, vì vậy bây giờ tôi có thể đi đến các vấn đề tiềm năng khác. –

1

Nó nên có thể để trích xuất các alpha từ oldRGBA và áp dụng nó vào newRGB trực tiếp:

newRGBA = colors.to_rgba(newRGB, alpha=oldRGBA[3]) 

Lưu ý: Tôi không bao giờ sử dụng matplotlib, tôi giả sử các thành phần alpha là yếu tố thứ 4 của màu

Các vấn đề liên quan