วิธีให้สีที่กำหนดเองของกราฟแท่งแพนด้า / matplotlib


86

ฉันเพิ่งเริ่มใช้ pandas / matplotlib แทน Excel เพื่อสร้างแผนภูมิแท่งแบบเรียงซ้อน ฉันพบปัญหา

(1) มีเพียง 5 สีใน colormap เริ่มต้นดังนั้นหากฉันมีมากกว่า 5 หมวดหมู่สีจะซ้ำ ฉันจะระบุสีเพิ่มเติมได้อย่างไร? ตามหลักการแล้วการไล่ระดับสีที่มีสีเริ่มต้นและสีสิ้นสุดและวิธีการสร้าง n สีแบบไดนามิกระหว่าง?

(2) สีไม่ถูกใจสายตา ฉันจะระบุชุดสีที่กำหนดเองได้อย่างไร? หรือการไล่ระดับสีก็ใช้ได้เช่นกัน

ตัวอย่างที่แสดงทั้งสองประเด็นข้างต้นอยู่ด้านล่าง:

  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)

และผลลัพธ์คือ:

ใส่คำอธิบายภาพที่นี่


มีวิธีง่ายๆในการรับ colormap บางส่วน ดูวิธีแก้ปัญหาด้านล่าง
Ted Petrou

คำตอบ:


120

คุณสามารถระบุcolorตัวเลือกเป็นรายการโดยตรงกับplotฟังก์ชัน

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)

ในการกำหนดรายการที่กำหนดเองของคุณเองคุณสามารถทำดังต่อไปนี้หรือเพียงแค่ค้นหาเทคนิค Matplotlib สำหรับการกำหนดรายการสีด้วยค่า RGB เป็นต้นคุณสามารถซับซ้อนได้มากเท่าที่คุณต้องการด้วยสิ่งนี้

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.

ตัวอย่างสุดท้ายให้การไล่ระดับสีอย่างง่ายสำหรับฉัน:

ใส่คำอธิบายภาพที่นี่

ฉันไม่ได้เล่นกับมันนานพอที่จะคิดหาวิธีบังคับให้ตำนานเลือกสีที่กำหนดไว้ แต่ฉันแน่ใจว่าคุณทำได้

โดยทั่วไปแล้วคำแนะนำที่สำคัญคือเพียงใช้ฟังก์ชันจาก Matplotlib โดยตรง การโทรหาพวกเขาจาก Pandas ก็โอเค แต่ฉันพบว่าคุณมีตัวเลือกและประสิทธิภาพที่ดีกว่าที่เรียกพวกเขาจาก Matplotlib โดยตรง


3
ข้อผิดพลาดเล็กน้อย: my_colors = [cycle (['b', 'r', 'g', 'y', 'k']) ถัดไป () สำหรับ i ในช่วง (len (df))] จะให้ 'b' ทุกครั้งใน python 2.7 คุณควรใช้ list (islice (cycle (['b', 'r', 'g', 'y', 'k']), None, len (df))) แทน
vkontori

ขอบคุณฉันคงไม่เข้าใจ อีกทางเลือกหนึ่งคือการสร้างวงจรก่อนจากนั้นเรียกใช้nextฟังก์ชันภายในความเข้าใจ
ely

ได้. มัน = วงจร (['b', 'r', 'g', 'y', 'k']); my_colors = [next (it) for i in xrange (len (df))] ก็จะตัดออกเช่นกัน ...
vkontori

1
เมื่อติดตั้งแพนด้าและ matplotlib ในวันนี้โค้ดด้านบนไม่ได้สร้างอะไรให้ฉันเลยแม้ว่ามันจะทำงานก็ตาม
kakyo

@kakyo คุณทำงานในล่ามปกติ IPython หรือจากเชลล์ (หรืออย่างอื่น) หรือไม่? ขึ้นอยู่กับประเภทของสภาพแวดล้อมที่คุณรันโค้ดนี้ภายในคุณอาจต้องเปิดโหมดโต้ตอบสำหรับ matplotlib หรือตั้งค่าpylab.ion()สำหรับ pylab แบบโต้ตอบ
ely

54

ฉันพบวิธีที่ง่ายที่สุดคือใช้colormapพารามิเตอร์.plot()ร่วมกับการไล่ระดับสีที่ตั้งไว้ล่วงหน้าอย่างใดอย่างหนึ่ง:

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

ใส่คำอธิบายภาพที่นี่

คุณสามารถค้นหาที่มีขนาดใหญ่รายการที่กำหนดไว้ล่วงหน้า colormaps ที่นี่

colormaps


19
ในกรณีของฉันสิ่งนี้ให้สีเดียวในทุกแท่ง
tsando

ฉันพบรายการ colormaps เหล่านี้ที่มีประโยชน์matplotlib.org/examples/color/colormaps_reference.html gallantlab.github.io/colormaps.html
Al Po

15

สำหรับคำตอบโดยละเอียดเกี่ยวกับการสร้าง colormaps ของคุณเองฉันขอแนะนำให้ไปที่หน้านี้

หากคำตอบนั้นใช้งานได้มากเกินไปคุณสามารถสร้างรายการสีของคุณเองได้อย่างรวดเร็วและส่งต่อไปยังcolorพารามิเตอร์ colormaps ทั้งหมดอยู่ในcmโมดูล matplotlib มาดูรายการค่าสี 30 RGB (บวกอัลฟา) จาก colormap ที่กลับด้านกัน ในการทำเช่นนั้นก่อนอื่นให้รับ colormap จากนั้นส่งต่อลำดับของค่าระหว่าง 0 ถึง 1 ที่นี่เราใช้np.linspaceเพื่อสร้าง 30 ค่าที่มีระยะห่างเท่ากันระหว่าง. 4 ถึง. 8 ซึ่งแสดงถึงส่วนนั้นของ colormap

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.      ],
       .....

จากนั้นเราสามารถใช้สิ่งนี้เพื่อลงจุดโดยใช้ข้อมูลจากโพสต์ต้นฉบับ:

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

ใส่คำอธิบายภาพที่นี่


2
นี่คือเอกสารสำหรับแผนที่สีอื่น ๆ นอกเหนือจากinferno_r: matplotlib.org/examples/color/colormaps_reference.html
tsando

1
ฉันติดตามตัวอย่างข้อมูลนี้ แต่อาร์เรย์สีของฉันมักจะมีค่าเหมือนกัน
FaCoffee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.