Biểu đồ thanh trong matplotlib sử dụng bản đồ màu

Sep 25 2020

Tôi có một df với hai cột:

  • y: các giá trị số khác nhau cho trục y
  • ngày: tên của bốn ngày khác nhau (Thứ Hai, Thứ Ba, Thứ Tư, Thứ Năm)

Tôi cũng có một bản đồ màu với bốn màu khác nhau mà tôi đã tự tạo và nó là một đối tượng ListedColorMap.

Tôi muốn tạo một biểu đồ thanh với bốn danh mục (ngày trong tuần) ở trục x và các giá trị tương ứng của chúng trong trục y. Đồng thời, tôi muốn mỗi thanh có một màu khác nhau bằng cách sử dụng bản đồ màu của tôi.

Đây là mã tôi đã sử dụng để tạo biểu đồ thanh của mình:

def my_barchart(my_df, my_cmap):
  fig = plt.figure()
  ax = fig.add_axes([0,0,1,1])
  ax.bar(my_df['days'], my_df['y'], color=my_cmap)
  return fig

Tuy nhiên, tôi gặp lỗi sau: "đối tượng kiểu 'ListedColormap' không có len ()", vì vậy có vẻ như tôi đang sử dụng my_cmap không đúng cách.

Nếu tôi xóa nó khỏi hàm và chạy nó, biểu đồ thanh của tôi trông vẫn ổn, ngoại trừ việc tất cả các thanh đều có cùng màu. Vì vậy, câu hỏi của tôi là: cách đúng để sử dụng bản đồ màu với biểu đồ thanh là gì?

Trả lời

4 JakeLevi Sep 25 2020 at 17:29

Đối colorsố muốn một chuỗi hoặc một giá trị RGB [A] (nó có thể là một màu duy nhất hoặc một chuỗi các màu với một cho mỗi điểm dữ liệu bạn đang vẽ). Bản đồ màu thường có thể gọi được với các số nổi trong phạm vi [0, 1].

Vì vậy, những gì bạn muốn làm là lấy các giá trị bạn muốn cho màu sắc cho mỗi thanh, chia tỷ lệ chúng thành phạm vi [0, 1], sau đó gọi my_cmapcác giá trị được thay đổi tỷ lệ đó.

Vì vậy, giả sử bạn muốn các màu tương ứng với các giá trị y (chiều cao của các thanh), sau đó bạn nên sửa đổi mã của mình như thế này (giả sử bạn đã gọi import numpy as nptrước đó):

def my_barchart(my_df, my_cmap):
    rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))

    fig = plt.figure()
    ax = fig.add_axes([0,0,1,1])
    ax.bar(my_df['days'], my_df['y'], color=my_cmap(rescale(my_df['y'])))
    return fig

Đây là một ví dụ tối thiểu khép kín về việc sử dụng colorđối số với đầu ra từ cmap:

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])

my_cmap = plt.get_cmap("viridis")
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))

plt.bar(x, y, color=my_cmap(rescale(y)))
plt.savefig("temp")

Đầu ra:

aprendiz Sep 25 2020 at 17:45

Được rồi, tôi đã tìm ra cách để làm điều này mà không cần phải chia tỷ lệ giá trị của mình:

def my_barchart(my_df, my_cmap):
  fig = plt.figure()
  ax = fig.add_axes([0,0,1,1])
  ax.bar(my_df['days'], my_df['y'], color=my_cmap.colors)
  return fig

Đơn giản chỉ cần thêm .colorssau khi my_cmaplàm việc!