2012-08-13 43 views
46

Tôi vừa mới bắt đầu sử dụng gấu trúc/matplotlib để thay thế cho Excel để tạo biểu đồ thanh xếp chồng lên nhau. Tôi đang gặp sự cốLàm thế nào để cung cấp cho một đồ thị thanh màu sắc/đồ thị màu sắc tùy chỉnh

(1) chỉ có 5 màu trong bản đồ mặc định, vì vậy nếu tôi có nhiều hơn 5 danh mục thì màu sẽ lặp lại. Làm cách nào tôi có thể chỉ định nhiều màu hơn? Lý tưởng nhất, một gradient với một màu bắt đầu và một màu kết thúc, và một cách để tự động tạo ra n màu sắc ở giữa?

(2) màu sắc không đẹp mắt lắm. Làm cách nào để chỉ định một bộ màu n tùy chỉnh? Hoặc, một gradient cũng sẽ hoạt động.

Một ví dụ minh họa cả hai điểm trên là dưới đây:

4 from matplotlib import pyplot 
    5 from pandas import * 
    6 import random 
    7 
    8 x = [{i:random.randint(1,5)} for i in range(10)] 
    9 df = DataFrame(x) 
10 
11 df.plot(kind='bar', stacked=True) 

Và kết quả là thế này:

enter image description here

+0

Có một cách khá dễ dàng để có được một bản đồ màu cục bộ. [Xem giải pháp dưới đây] (https://stackoverflow.com/a/47146928/3707607) –

Trả lời

69

Bạn có thể chỉ định các tùy chọn color như một danh sách trực tiếp đến plot chức năng.

from matplotlib import pyplot as plt 
from itertools import cycle, islice 
import pandas, numpy as np # I find np.random.randint to be better 

# Make the data 
x = [{i:np.random.randint(1,5)} for i in range(10)] 
df = pandas.DataFrame(x) 

# Make a list by cycling through the colors you care about 
# to match the length of your data. 
my_colors = list(islice(cycle(['b', 'r', 'g', 'y', 'k']), None, len(df))) 

# Specify this list of colors as the `color` option to `plot`. 
df.plot(kind='bar', stacked=True, color=my_colors) 

Để xác định danh sách tùy chỉnh của riêng bạn, bạn có thể làm một vài điều sau đây, hoặc chỉ tìm kiếm các kỹ thuật Matplotlib để xác định một mục màu bởi các giá trị RGB của nó, vv Bạn có thể có được càng phức tạp như bạn muốn Với cái này.

my_colors = ['g', 'b']*5 # <-- this concatenates the list to itself 5 times. 
my_colors = [(0.5,0.4,0.5), (0.75, 0.75, 0.25)]*5 # <-- make two custom RGBs and repeat/alternate them over all the bar elements. 
my_colors = [(x/10.0, x/20.0, 0.75) for x in range(len(df))] # <-- Quick gradient example along the Red/Green dimensions. 

Ví dụ cuối cùng mang lại sự theo gradient đơn giản về màu sắc cho tôi:

enter image description here

Tôi không chơi với nó đủ lâu để tìm ra cách để buộc các huyền thoại để nhặt xác định màu sắc, nhưng tôi chắc chắn bạn có thể làm điều đó.

Nói chung, mặc dù, một lời khuyên lớn là chỉ cần sử dụng các chức năng từ Matplotlib trực tiếp. Gọi chúng từ Pandas là OK, nhưng tôi thấy bạn có được lựa chọn tốt hơn và hiệu suất gọi chúng trực tiếp từ Matplotlib.

+3

Lỗi nhỏ: my_colors = [cycle (['b', 'r', 'g', 'y', 'k' ]). next() cho i trong phạm vi (len (df))] sẽ cho 'b' mỗi lần trong python 2,7. Bạn nên sử dụng danh sách (islice (chu kỳ (['b', 'r', 'g', 'y', 'k']), Không, len (df))) thay thế. – vkontori

+0

Cảm ơn, tôi có lẽ sẽ không bắt được điều đó. Một tùy chọn khác là tạo chu trình đầu tiên, sau đó chỉ cần gọi hàm 'next' của nó bên trong hiểu. – ely

+0

Yup. it = cycle (['b', 'r', 'g', 'y', 'k']); my_colors = [next (it) cho i in xrange (len (df))] cũng sẽ cắt nó ... – vkontori

26

tôi thấy cách dễ nhất là sử dụng các tham số colormap trong .plot() với một trong những gradient màu cài sẵn:

df.plot(kind='bar', stacked=True, colormap='Paired') 

enter image description here

Bạn có thể tìm thấy một lượng lớn list of preset colormaps here.

colormaps

1

Đối với một câu trả lời chi tiết hơn về việc tạo ra colormaps riêng của bạn, tôi rất khuyên bạn nên truy this page

Nếu câu trả lời đó là quá nhiều công việc, bạn có thể nhanh chóng làm cho danh sách của riêng bạn của màu sắc và vượt qua chúng để thông số color. Tất cả các bản đồ màu nằm trong mô-đun matplotlib cm. Hãy lấy danh sách 30 giá trị màu RGB (cộng với alpha) từ bản đồ inferno colapap đảo ngược. Để làm như vậy, trước tiên hãy lấy bản đồ màu và chuyển nó một chuỗi các giá trị từ 0 đến 1. Ở đây, chúng tôi sử dụng np.linspace để tạo ra 30 giá trị khoảng cách bằng nhau giữa .4 và .8 đại diện cho phần đó của bản đồ màu.

from matplotlib import cm 
color = cm.inferno_r(np.linspace(.4,.8, 30)) 
color 

array([[ 0.865006, 0.316822, 0.226055, 1.  ], 
     [ 0.851384, 0.30226 , 0.239636, 1.  ], 
     [ 0.832299, 0.283913, 0.257383, 1.  ], 
     [ 0.817341, 0.270954, 0.27039 , 1.  ], 
     [ 0.796607, 0.254728, 0.287264, 1.  ], 
     [ 0.775059, 0.239667, 0.303526, 1.  ], 
     [ 0.758422, 0.229097, 0.315266, 1.  ], 
     [ 0.735683, 0.215906, 0.330245, 1.  ], 
     ..... 

Sau đó, chúng ta có thể sử dụng để vẽ - bằng cách sử dụng dữ liệu từ các bài bản gốc:

import random 
x = [{i:random.randint(1,5)} for i in range(30)] 
df = pd.DataFrame(x) 
df.plot(kind='bar', stacked=True, color=color, legend=False, figsize=(12,4)) 

enter image description here

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