2013-05-30 70 views
30

Tôi có vấn đề sau, tôi muốn tạo bản đồ màu của riêng mình (đỏ-mix-violet-mix-blue) ánh xạ tới các giá trị từ -2 đến +2 và muốn sử dụng nó để tô màu các điểm trong cốt truyện của tôi. Cốt truyện sau đó sẽ có màu sắc ở bên phải.

Đó là cách tôi tạo bản đồ cho đến thời điểm này. Nhưng tôi không thực sự chắc chắn nếu nó pha trộn các màu sắc.Tạo bản đồ màu riêng bằng cách sử dụng matplotlib và thang màu âm mưu

cmap = matplotlib.colors.ListedColormap(["red","violet","blue"], name='from_list', N=None) 
m = cm.ScalarMappable(norm=norm, cmap=cmap) 


Bằng cách đó tôi ánh xạ màu cho giá trị.

colors = itertools.cycle([m.to_rgba(1.22), ..]) 


Sau đó, tôi vẽ nó:

for i in range(0, len(array_dg)): 
    plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next()) 


vấn đề của tôi là:
1. Tôi không thể vẽ quy mô màu.
2. Tôi không hoàn toàn chắc chắn nếu quy mô của tôi đang tạo ra một màu sắc tiếp tục (mịn).

+0

Ông có thể làm rõ câu hỏi của bạn một chút? Ví dụ, 'c =' chỉ định màu của đường kẻ, trong khi bạn đang nói về các điểm. Bạn chỉ có thể chỉ định một 'markerfacecolor', phân tán có thể là một lựa chọn tốt hơn nếu bạn thực sự muốn điểm. Và thực sự 'ListedColormap' được liệt kê, không liên tục, xem' LinearSegmentedColormap'. –

+0

Điều đó thật kỳ lạ, nó được cho là điểm và nó trông giống như điểm. – Trollbrot

+0

Bạn có thể tắt khóa học, nhưng đó là những gì bạn nên làm rõ. Chúng tôi không thể thấy phong cách cốt truyện bạn đang sử dụng. Nếu bạn sử dụng 'plt.plot (giá trị, 'o')', bạn sẽ chỉ vẽ các dấu và không có dòng, nhưng các điểm đánh dấu sẽ có một màu cố định mà không (và không thể) thay đổi theo giá trị. –

Trả lời

53

Có ví dụ minh họa là how to create custom colormaps here. Chuỗi tài liệu là điều cần thiết để hiểu ý nghĩa của cdict. Một khi bạn nhận được rằng dưới vành đai của bạn, bạn có thể sử dụng một cdict như thế này:

cdict = {'red': ((0.0, 1.0, 1.0), 
        (0.1, 1.0, 1.0), # red 
        (0.4, 1.0, 1.0), # violet 
        (1.0, 0.0, 0.0)), # blue 

     'green': ((0.0, 0.0, 0.0), 
        (1.0, 0.0, 0.0)), 

     'blue': ((0.0, 0.0, 0.0), 
        (0.1, 0.0, 0.0), # red 
        (0.4, 1.0, 1.0), # violet 
        (1.0, 1.0, 0.0)) # blue 
      } 

Mặc dù định dạng cdict cung cấp cho bạn rất nhiều tính linh hoạt, tôi tìm cho đơn giản gradients định dạng của nó là khá unintuitive. Đây là một chức năng hữu ích để giúp tạo LinearSegmentedColormaps đơn giản:

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


def make_colormap(seq): 
    """Return a LinearSegmentedColormap 
    seq: a sequence of floats and RGB-tuples. The floats should be increasing 
    and in the interval (0,1). 
    """ 
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3] 
    cdict = {'red': [], 'green': [], 'blue': []} 
    for i, item in enumerate(seq): 
     if isinstance(item, float): 
      r1, g1, b1 = seq[i - 1] 
      r2, g2, b2 = seq[i + 1] 
      cdict['red'].append([item, r1, r2]) 
      cdict['green'].append([item, g1, g2]) 
      cdict['blue'].append([item, b1, b2]) 
    return mcolors.LinearSegmentedColormap('CustomMap', cdict) 


c = mcolors.ColorConverter().to_rgb 
rvb = make_colormap(
    [c('red'), c('violet'), 0.33, c('violet'), c('blue'), 0.66, c('blue')]) 
N = 1000 
array_dg = np.random.uniform(0, 10, size=(N, 2)) 
colors = np.random.uniform(-2, 2, size=(N,)) 
plt.scatter(array_dg[:, 0], array_dg[:, 1], c=colors, cmap=rvb) 
plt.colorbar() 
plt.show() 

enter image description here


Bằng cách này, các for-loop

for i in range(0, len(array_dg)): 
    plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next()) 

lô một điểm cho mỗi cuộc gọi đến plt.plot. Điều này sẽ làm việc cho một số lượng nhỏ các điểm, nhưng sẽ trở nên rất chậm cho nhiều điểm. plt.plot chỉ có thể vẽ một màu, nhưng plt.scatter có thể gán màu khác nhau cho mỗi chấm. Vì vậy, plt.scatter là con đường để đi.

+0

Tôi gặp sự cố. Tôi cũng muốn có một biểu tượng điểm đánh dấu khác nhau theo màu (tôi có 13 màu khác nhau). Nhưng âm mưu phân tán chỉ cho phép một điểm đánh dấu trên mỗi ô, hay tôi bỏ lỡ một thứ gì đó? – Trollbrot

+0

Trong trường hợp đó, bạn sẽ cần phải gọi 'plt.scatter' (hoặc' plt.plot') một lần cho mỗi kết hợp màu/điểm đánh dấu. – unutbu

+0

Tại sao tôi không thể sử dụng bản đồ màu được tạo bằng hàm tuyệt vời này trong plt.set_cmap()? Lỗi này rất dài, dòng cuối cùng là ValueError: Bản đồ tùy chỉnh Colormap không được nhận dạng. – Phlya

10

Nếu bạn muốn tự động hóa việc tạo một bản đồ phân kỳ tùy chỉnh thường được sử dụng cho surface plots, mô-đun này kết hợp với phương pháp @unutbu hoạt động tốt cho tôi.

def diverge_map(high=(0.565, 0.392, 0.173), low=(0.094, 0.310, 0.635)): 
    ''' 
    low and high are colors that will be used for the two 
    ends of the spectrum. they can be either color strings 
    or rgb color tuples 
    ''' 
    c = mcolors.ColorConverter().to_rgb 
    if isinstance(low, basestring): low = c(low) 
    if isinstance(high, basestring): high = c(high) 
    return make_colormap([low, c('white'), 0.5, c('white'), high]) 

Giá trị cao và thấp có thể là tên màu chuỗi hoặc bộ rgb. Đây là kết quả sử dụng surface plot demo: enter image description here

+0

Chức năng rất gọn gàng! – Thriveth

6

Kể từ khi các phương pháp được sử dụng trong câu trả lời khác có vẻ khá phức tạp đối với nhiệm vụ dễ dàng như vậy, đây là một câu trả lời mới:

Thay vì một ListedColormap, trong đó sản xuất một rời rạc bản đồ màu, bạn có thể sử dụng LinearSegmentedColormap.Điều này có thể dễ dàng được tạo ra từ một danh sách bằng cách sử dụng phương thức from_list.

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

x,y,c = zip(*np.random.rand(30,3)*4-2) 

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["red","violet","blue"]) 

plt.scatter(x,y,c=c, cmap=cmap) 
plt.colorbar() 
plt.show() 

enter image description here

+0

Bây giờ bạn sẽ vượt qua phạm vi được xác định riêng như thế nào, ví dụ: 'red' tương ứng với' -5', 'violet' thành' 1' và 'xanh' thành' 100'? Tôi rất cảm kích nếu bạn có thể xem câu hỏi mà tôi đã hỏi [ở đây] (https://stackoverflow.com/questions/47697782/how-to-create-a-customized-colormap-and-use-it-for- phạm vi khác nhau của dữ liệu). – Cleb

+1

Sử dụng đối số 'vmin' và' vmax' hoặc 'norm' của phương pháp vẽ đồ thị tương ứng. – ImportanceOfBeingErnest

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