วิธีการรับเส้นสีที่แตกต่างกันสำหรับแปลงที่แตกต่างกันในรูปเดียว?


202

ฉันใช้matplotlibเพื่อสร้างแปลง ฉันต้องระบุแต่ละพล็อตที่มีสีแตกต่างกันซึ่ง Python ควรสร้างขึ้นโดยอัตโนมัติ

คุณช่วยให้วิธีการใส่สีที่แตกต่างกันสำหรับแปลงที่แตกต่างกันในรูปเดียวกันได้ไหม

คำตอบ:


424

Matplotlib ทำสิ่งนี้ตามค่าเริ่มต้น

เช่น:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)
plt.show()

พล็อตพื้นฐานแสดงให้เห็นถึงการขี่จักรยานสี

และอย่างที่คุณอาจทราบแล้วคุณสามารถเพิ่มคำอธิบายภาพได้อย่างง่ายดาย:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

เนื้อเรื่องพื้นฐานพร้อมคำอธิบาย

หากคุณต้องการควบคุมสีที่จะขี่จักรยานผ่าน:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.gca().set_color_cycle(['red', 'green', 'blue', 'yellow'])

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

พล็อตที่แสดงการควบคุมการเปลี่ยนสีเริ่มต้น

หากคุณไม่คุ้นเคยกับ matplotlib การสอนเป็นจุดเริ่มต้นที่ดี

แก้ไข:

ก่อนอื่นถ้าคุณมีหลายสิ่ง (> 5) ของสิ่งที่คุณต้องการพล็อตในหนึ่งร่างทั้ง:

  1. วางไว้ในแปลงที่แตกต่างกัน (พิจารณาใช้สองสาม subplots ในหนึ่งรูป), หรือ
  2. ใช้สิ่งอื่นที่ไม่ใช่สี (เช่นรูปแบบเครื่องหมายหรือความหนาของเส้น) เพื่อแยกความแตกต่างระหว่างพวกเขา

มิฉะนั้นคุณจะจบลงด้วยพล็อตที่ยุ่งมาก ! เป็นคนดีที่เคยอ่านสิ่งที่คุณกำลังทำและอย่าพยายามยัด 15 สิ่งที่แตกต่างกันลงในรูปเดียว !!

นอกเหนือจากนั้นคนจำนวนมากตาบอดสีจนถึงองศาที่แตกต่างและการแยกแยะระหว่างสีที่แตกต่างกันมากมายนั้นเป็นเรื่องยากสำหรับผู้คนมากกว่าที่คุณจะรู้

ถ้าคุณต้องการที่จะใส่ 20 บรรทัดในหนึ่งแกนด้วย 20 สีที่ต่างกันนี่เป็นวิธีหนึ่งที่จะทำได้:

import matplotlib.pyplot as plt
import numpy as np

num_plots = 20

# Have a look at the colormaps here and decide which one you'd like:
# http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html
colormap = plt.cm.gist_ncar
plt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))

# Plot several different functions...
x = np.arange(10)
labels = []
for i in range(1, num_plots + 1):
    plt.plot(x, i * x + 5 * i)
    labels.append(r'$y = %ix + %i$' % (i, 5*i))

# I'm basically just demonstrating several different legend options here...
plt.legend(labels, ncol=4, loc='upper center', 
           bbox_to_anchor=[0.5, 1.1], 
           columnspacing=1.0, labelspacing=0.0,
           handletextpad=0.0, handlelength=1.5,
           fancybox=True, shadow=True)

plt.show()

สีที่ไม่ซ้ำกันสำหรับ 20 บรรทัดตาม colormap ที่กำหนด


17
หมายเหตุสำหรับตัวอย่างล่าสุดในเวอร์ชันใหม่ของ matplotlib รายการset_color_cycleถูกคัดค้านดังนั้นบรรทัดนั้นควรจะเป็นplt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))และเพียงแค่เปลี่ยนplt.cm.YOUR_PREFERED_COLOR_MAPให้เหมาะกับความต้องการของคุณ
เนท

1
@ JoeKington: คำอธิบายนั้นยอดเยี่ยมมากขอบคุณมาก
Rika

มันเยี่ยมมาก มีวิธีที่จะทำให้พวกเขาโต้ตอบ? ตัวอย่างเช่นใน RI แปลง ggplot เป็น ggplotly () และพล็อตกลายเป็น html แบบโต้ตอบ
kRazzy R

ฉันเชื่อว่า OP รู้ว่าสี Matplotlib เป็นเส้นโค้งที่แตกต่างกันอย่างเหมาะสมในเนื้อเรื่องเดียว (ในหนึ่งเดียวaxes) และถามเกี่ยวกับการเปลี่ยนสีของเส้นเดี่ยวในรูปแบบต่าง ๆ (ต่างกันaxes) ... นั่นบอกว่าเป็นคำตอบที่ดี คำถาม (อาจแตกต่างจากสิ่งที่ OP ถาม แต่ไม่มีใครสามารถบอกได้เพราะพวกเขาถามคำถามเดียวและหายไป!) - +1
gboffi

37

ตั้งค่าพวกเขาในภายหลัง

หากคุณไม่ทราบจำนวนพล็อตที่คุณจะพล็อตคุณสามารถเปลี่ยนสีได้เมื่อคุณได้พล็อตพวกเขาดึงข้อมูลจำนวนโดยตรงจากพล็อตที่ใช้.linesฉันใช้วิธีนี้:

ข้อมูลสุ่มบางส่วน

import matplotlib.pyplot as plt
import numpy as np

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)


for i in range(1,15):
    ax1.plot(np.array([1,5])*i,label=i)

ส่วนของรหัสที่คุณต้องการ:

colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired   
colors = [colormap(i) for i in np.linspace(0, 1,len(ax1.lines))]
for i,j in enumerate(ax1.lines):
    j.set_color(colors[i])
  

ax1.legend(loc=2)

ผลที่ได้คือ:ป้อนคำอธิบายรูปภาพที่นี่


8

TL; DRไม่มีก็ไม่สามารถทำได้โดยอัตโนมัติ ใช่มันเป็นไปได้

import matplotlib.pyplot as plt
my_colors = plt.rcParams['axes.prop_cycle']() # <<< note that we CALL the prop_cycle
fig, axes = plt.subplots(2,3)
for ax in axes.flatten(): ax.plot((0,1), (0,1), **next(my_colors))

ป้อนคำอธิบายรูปภาพที่นี่ แต่ละพล็อต ( axes) ในรูป ( figure) มีวงจรสีเป็นของตัวเอง - หากคุณไม่ได้บังคับสีที่แตกต่างกันสำหรับแต่ละพล็อตแผนการทั้งหมดใช้ลำดับสีเดียวกัน แต่ถ้าเราขยายความหมายของ "อัตโนมัติ" ก็สามารถทำได้


OP เขียน

[... ] ฉันต้องระบุแต่ละพล็อตด้วยสีที่แตกต่างซึ่งควรสร้างขึ้นโดยอัตโนมัติโดย [Matplotlib]

แต่ ... Matplotlib สร้างสีที่ต่างกันโดยอัตโนมัติสำหรับแต่ละโค้งที่ต่างกัน

In [10]: import numpy as np
    ...: import matplotlib.pyplot as plt

In [11]: plt.plot((0,1), (0,1), (1,2), (1,0));
Out[11]:

ป้อนคำอธิบายรูปภาพที่นี่

เหตุใดจึงต้องร้องขอ OP ถ้าเราอ่านต่อไปเรามี

คุณช่วยให้วิธีการใส่สีที่แตกต่างกันสำหรับแปลงที่แตกต่างกันในรูปเดียวกันได้ไหม

และมันก็สมเหตุสมผลเนื่องจากแต่ละพล็อต ( axesในพหูพจน์ของ Matplotlib) มีของตัวเองcolor_cycle(หรือมากกว่าในปีพ. ศ. 2561 prop_cycle) และพล็อตแต่ละอัน ( axes) ใช้สีเดียวกันในลำดับเดียวกัน

In [12]: fig, axes = plt.subplots(2,3)

In [13]: for ax in axes.flatten():
    ...:     ax.plot((0,1), (0,1))

ป้อนคำอธิบายรูปภาพที่นี่

หากนี่เป็นความหมายของคำถามต้นฉบับความเป็นไปได้อย่างหนึ่งคือการตั้งชื่อสีที่แตกต่างกันอย่างชัดเจนสำหรับแต่ละพล็อต

หากแปลง (ตามที่มักจะเกิดขึ้น) ถูกสร้างขึ้นในวงเราจะต้องมีตัวแปรวงเพิ่มเติมเพื่อแทนที่สีโดยอัตโนมัติเลือกโดย Matplotlib

In [14]: fig, axes = plt.subplots(2,3)

In [15]: for ax, short_color_name in zip(axes.flatten(), 'brgkyc'):
    ...:     ax.plot((0,1), (0,1), short_color_name)

ป้อนคำอธิบายรูปภาพที่นี่

ความเป็นไปได้อีกอย่างหนึ่งก็คือยกตัวอย่างวัตถุที่เป็นนักปั่น

from cycler import cycler
my_cycler = cycler('color', ['k', 'r']) * cycler('linewidth', [1., 1.5, 2.])
actual_cycler = my_cycler()

fig, axes = plt.subplots(2,3)
for ax in axes.flat:
    ax.plot((0,1), (0,1), **next(actual_cycler))

ป้อนคำอธิบายรูปภาพที่นี่

ทราบว่าtype(my_cycler)เป็นcycler.Cyclerแต่เป็นtype(actual_cycler)itertools.cycle


3

ฉันต้องการเสนอการปรับปรุงเล็กน้อยในคำตอบลูปสุดท้ายที่กำหนดในโพสต์ก่อนหน้า (โพสต์นั้นถูกต้องและควรได้รับการยอมรับ) ข้อสันนิษฐานโดยนัยเมื่อทำการติดฉลากตัวอย่างสุดท้ายคือการplt.label(LIST)ใส่หมายเลข X ในLISTบรรทัดที่สอดคล้องกับเวลา Xth ที่plotถูกเรียก ฉันพบปัญหาเกี่ยวกับวิธีการนี้มาก่อน วิธีที่แนะนำในการสร้างตำนานและกำหนดป้ายกำกับของตนเองต่อเอกสารประกอบ matplotlibs ( http://matplotlib.org/users/legend_guide.html#adjusting-the-order-of-legend-item ) คือการรู้สึกอบอุ่น พร้อมกับแปลงที่คุณคิดว่าพวกเขาทำ:

...
# Plot several different functions...
labels = []
plotHandles = []
for i in range(1, num_plots + 1):
    x, = plt.plot(some x vector, some y vector) #need the ',' per ** below
    plotHandles.append(x)
    labels.append(some label)
plt.legend(plotHandles, labels, 'upper left',ncol=1)

**: Matplotlib Legends ไม่ทำงาน


3
เพียงแค่ fyi: คุณยังสามารถใช้ "ป้ายกำกับ" kwarg เพื่อพล็อตแล้วเรียกคำอธิบายโดยไม่มีข้อโต้แย้งใด ๆ
Joe Kington
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.