Matplotlib पर स्कैटर प्लॉट में प्रत्येक श्रृंखला के लिए अलग-अलग रंग सेट करना


162

मान लीजिए कि मेरे पास तीन डेटा सेट हैं:

X = [1,2,3,4]
Y1 = [4,8,12,16]
Y2 = [1,4,9,16]

मैं यह साजिश रच सकता हूँ:

from matplotlib import pyplot as plt
plt.scatter(X,Y1,color='red')
plt.scatter(X,Y2,color='blue')
plt.show()

मैं 10 सेटों के साथ यह कैसे कर सकता हूं?

मैंने इसके लिए खोज की और जो भी मैं पूछ रहा हूं, उसका कोई संदर्भ मिल सकता है।

संपादित करें: मेरा प्रश्न स्पष्ट (उम्मीद)

यदि मैं कई बार स्कैटर कॉल करता हूं, तो मैं प्रत्येक स्कैटर पर एक ही रंग सेट कर सकता हूं। इसके अलावा, मुझे पता है कि मैं मैन्युअल रूप से एक रंग सरणी सेट कर सकता हूं, लेकिन मुझे यकीन है कि ऐसा करने का एक बेहतर तरीका है। मेरा सवाल यह है कि, "मैं अपने कई डेटा सेट को स्वचालित रूप से कैसे अलग-अलग रंग के साथ बिखेर सकता हूं।

यदि वह मदद करता है, तो मैं आसानी से प्रत्येक डेटा सेट के लिए एक अद्वितीय संख्या निर्दिष्ट कर सकता हूं।


1
यहाँ quesiton क्या है? रंग एक सरणी के रूप में अच्छी तरह से हो सकता है, लेकिन क्या आप केवल कई बार स्कैटर कॉलिंग के साथ हल नहीं कर सकते हैं?
सेबर्ग

1
अगर मैं कई बार स्कैटर कॉल करता हूं, तो मुझे वही रंग मिलते हैं। मैं अपना सवाल अपडेट करूंगा।
योताम

जवाबों:


269

मुझे नहीं पता कि 'मैन्युअल' से आपका क्या मतलब है। आप एक colourmap चुन सकते हैं और आसानी से पर्याप्त रंग सरणी बना सकते हैं:

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

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]

colors = cm.rainbow(np.linspace(0, 1, len(ys)))
for y, c in zip(ys, colors):
    plt.scatter(x, y, color=c)

विभिन्न रंगों के साथ मैटलोट्लिब ग्राफ

या आप अपने खुद के रंग साइकलर का उपयोग कर सकते हैं itertools.cycleऔर उन रंगों को निर्दिष्ट कर सकते हैं जिन्हें आप लूप करना चाहते हैं, जिसको nextआप चाहते हैं। उदाहरण के लिए, 3 रंगों के साथ:

import itertools

colors = itertools.cycle(["r", "b", "g"])
for y in ys:
    plt.scatter(x, y, color=next(colors))

केवल 3 रंगों के साथ Matplotlib ग्राफ

यह सोचने के लिए आओ, शायद यह zipन तो पहले वाले के साथ उपयोग करने के लिए क्लीनर है :

colors = iter(cm.rainbow(np.linspace(0, 1, len(ys))))
for y in ys:
    plt.scatter(x, y, color=next(colors))

1
+1। एक पुनरावृत्ति चक्र शायद इस स्थिति में एक अच्छा विचार नहीं है, हालांकि, यह एक ही रंग वाले कई डेटासेट के साथ समाप्त होगा।
डेविड रॉबिन्सन

1
@DavidRobinson: यदि आप सभी दस निर्दिष्ट करते हैं, तो नहीं, हालांकि मैं सहमत हूं कि साइकिलिंग उद्देश्य वहां पर हार मान लेता है:: ^)
DSM

सटीक रूप से- तो यह एक चक्र नहीं है :)
डेविड रॉबिन्सन

4
@macrocosme: मेरे लिए काम करता है। plt.legend(['c{}'.format(i) for i in range(len(ys))], loc=2, bbox_to_anchor=(1.05, 1), borderaxespad=0., fontsize=11)ऊपर से नीचे जोड़ने पर मुझे रंगों के साथ एक किंवदंती मिलती है।
DSM

जब आप कुछ रंगों से बचना चाहते हैं तो itertools समाधान बहुत अच्छा है। मेरे मामले में चूंकि पृष्ठभूमि काली है, इसलिए मैं काले रंग से बचना चाहता हूं।
फाब्रीजियो

50

Matplotlib में विभिन्न रंगों में बिंदुओं के साथ भूखंडों को प्लॉट करने का सामान्य तरीका एक पैरामीटर के रूप में रंगों की सूची को पास करना है।

उदाहरण के लिए:

import matplotlib.pyplot
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=['red','green','blue'])

3 रंग

जब आपके पास सूचियों की एक सूची हो और आप उन्हें प्रति सूची में रंगीन करना चाहते हैं। मुझे लगता है कि सबसे सुंदर तरीका यह है कि @DSM द्वारा शर्करा, बस एक लूप करें जिससे स्कैटर को कई कॉल करें।

लेकिन अगर किसी कारण से आप इसे केवल एक कॉल के साथ करना चाहते हैं, तो आप रंगों की एक बड़ी सूची बना सकते हैं, एक सूची समझ और थोड़ा सा फर्श विभाजन के साथ:

import matplotlib
import numpy as np

X = [1,2,3,4]
Ys = np.array([[4,8,12,16],
      [1,4,9,16],
      [17, 10, 13, 18],
      [9, 10, 18, 11],
      [4, 15, 17, 6],
      [7, 10, 8, 7],
      [9, 0, 10, 11],
      [14, 1, 15, 5],
      [8, 15, 9, 14],
       [20, 7, 1, 5]])
nCols = len(X)  
nRows = Ys.shape[0]

colors = matplotlib.cm.rainbow(np.linspace(0, 1, len(Ys)))

cs = [colors[i//len(X)] for i in range(len(Ys)*len(X))] #could be done with numpy's repmat
Xs=X*nRows #use list multiplication for repetition
matplotlib.pyplot.scatter(Xs,Ys.flatten(),color=cs)

सभी को प्लॉट किया गया

cs = [array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 ...
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00])]

19

एक आसान तय

यदि आपके पास केवल एक प्रकार के संग्रह हैं (जैसे बिना किसी त्रुटि सलाखों के साथ बिखराव) तो आप रंगों को बदल सकते हैं उसके बाद आपने उन्हें प्लॉट किया है, कभी-कभी प्रदर्शन करना आसान होता है।

import matplotlib.pyplot as plt
from random import randint
import numpy as np

#Let's generate some random X, Y data X = [ [frst group],[second group] ...]
X = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
Y = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
labels = range(1,len(X)+1)

fig = plt.figure()
ax = fig.add_subplot(111)
for x,y,lab in zip(X,Y,labels):
        ax.scatter(x,y,label=lab)

कोड का एकमात्र टुकड़ा जो आपको चाहिए:

#Now this is actually the code that you need, an easy fix your colors just cut and paste not you need ax.
colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired  
colorst = [colormap(i) for i in np.linspace(0, 0.9,len(ax.collections))]       
for t,j1 in enumerate(ax.collections):
    j1.set_color(colorst[t])


ax.legend(fontsize='small')

जब आप एक ही सबप्लॉट में कई अलग-अलग तितर बितर भूखंड होते हैं तब भी आउटपुट आपको अलग-अलग रंग देता है।

यहां छवि विवरण दर्ज करें


यह बहुत अच्छा है, लेकिन आप इस फ़ंक्शन के साथ एक ही रंग के एररबर्स को कैसे जोड़ सकते हैं? @GM
PEBKAC

1
हाय @PEBKAC, इसे इंगित करने के लिए धन्यवाद, मैंने इस दोपहर को उस मामले में भी काम करने के लिए कड़ी मेहनत की है, लेकिन मुझे कोई समाधान नहीं मिला, इसलिए मैंने सवाल संपादित किया और अन्य उपयोगकर्ताओं को चेतावनी दी। धन्यवाद!
GM

हाय @GM, क्षमा करें मैंने समाधान को अंतिम रूप देने से पहले कुछ टिप्पणियां पोस्ट की हैं, जो यहां वर्णित हैं: stackoverflow.com/q/51444364/7541421
PEBKAC

1
मैंने स्कैटर प्लॉट में प्रत्येक श्रृंखला के लिए रंगों को असाइन करने के लिए एक और विधि का उपयोग किया। अब यह काम करता है, दुर्भाग्य से मैं आपके सुरुचिपूर्ण समाधान के साथ आगे नहीं बढ़ सका जब यह एररबार्स आया, फिर भी मैं आपके सुपर सहायक पोस्ट के लिए वास्तव में आभारी हूं! चीयर्स!
PEBKAC

7

आप हमेशा plot()फ़ंक्शन का उपयोग कर सकते हैं जैसे:

import matplotlib.pyplot as plt

import numpy as np

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]
plt.figure()
for y in ys:
    plt.plot(x, y, 'o')
plt.show()

बिखराव के रूप में साजिश लेकिन रंग बदलता है


6

यह सवाल जनवरी 2013 से पहले थोड़ा मुश्किल है और matplotlib 1.3.1 (अगस्त 2013), जो सबसे पुराना स्थिर संस्करण है जिसे आप matpplotlib वेबसाइट पर पा सकते हैं। लेकिन इसके बाद यह काफी तुच्छ है।

क्योंकि वर्तमान असाइनमेंट का matplotlib.pylab.scatterसमर्थन संस्करण : रंग नाम स्ट्रिंग की सरणी, रंगीन मानचित्र के साथ फ्लोट संख्या की संख्या, आरजीबी या आरजीबीए की सरणी।

यह उत्तर 2015 में स्वयं के 2013 संस्करण को सही करने के लिए @ ऑक्सिनाबॉक्स के अंतहीन जुनून के लिए समर्पित है।


आपके पास एक कॉल में कई रंग के साथ स्कैटर कमांड का उपयोग करने का दो विकल्प हैं।

  1. pylab.scatterकमांड सपोर्ट के रूप में आरजीबीए एरे का उपयोग करें जो भी आप करना चाहते हैं;

  2. 2013 की शुरुआत में, ऐसा करने का कोई तरीका नहीं है, क्योंकि कमांड केवल पूरे तितर बितर बिंदु संग्रह के लिए एकल रंग का समर्थन करता है। जब मैं अपनी १००००-लाइन की परियोजना कर रहा था, तो मैं इसे दूर करने के लिए एक सामान्य समाधान का पता लगा रहा हूं। इसलिए यह बहुत कठिन है, लेकिन मैं इसे आकार, रंग, आकार और पारदर्शी दोनों में कर सकता हूं। यह ट्रिक पथ संग्रह, लाइन संग्रह को आकर्षित करने के लिए भी लागू की जा सकती है ...।

कोड भी स्रोत कोड से प्रेरित है pyplot.scatter, मैंने अभी-अभी डुप्लिकेट किया है कि यह क्या आकर्षित करने के लिए ट्रिगर के बिना बिखराव करता है।

आदेश pyplot.scatterएक वापसी PatchCollectionफ़ाइल "matplotlib / collections.py" एक निजी चर में वस्तु, _facecolorsमें Collectionवर्ग और एक विधि set_facecolors

तो जब भी आपके पास खींचने के लिए एक बिखरे हुए बिंदु हों तो आप यह कर सकते हैं:

# rgbaArr is a N*4 array of float numbers you know what I mean
# X is a N*2 array of coordinates
# axx is the axes object that current draw, you get it from
# axx = fig.gca()

# also import these, to recreate the within env of scatter command 
import matplotlib.markers as mmarkers
import matplotlib.transforms as mtransforms
from matplotlib.collections import PatchCollection
import matplotlib.markers as mmarkers
import matplotlib.patches as mpatches


# define this function
# m is a string of scatter marker, it could be 'o', 's' etc..
# s is the size of the point, use 1.0
# dpi, get it from axx.figure.dpi
def addPatch_point(m, s, dpi):
    marker_obj = mmarkers.MarkerStyle(m)
    path = marker_obj.get_path()
    trans = mtransforms.Affine2D().scale(np.sqrt(s*5)*dpi/72.0)
    ptch = mpatches.PathPatch(path, fill = True, transform = trans)
    return ptch

patches = []
# markerArr is an array of maker string, ['o', 's'. 'o'...]
# sizeArr is an array of size float, [1.0, 1.0. 0.5...]

for m, s in zip(markerArr, sizeArr):
    patches.append(addPatch_point(m, s, axx.figure.dpi))

pclt = PatchCollection(
                patches,
                offsets = zip(X[:,0], X[:,1]),
                transOffset = axx.transData)

pclt.set_transform(mtransforms.IdentityTransform())
pclt.set_edgecolors('none') # it's up to you
pclt._facecolors = rgbaArr

# in the end, when you decide to draw
axx.add_collection(pclt)
# and call axx's parent to draw_idle()

इसलिए यह पढ़ने के लिए थोड़े जटिल है और 2013 में मैंने 1 साल के लिए अजगर का इस्तेमाल किया। तो लोग यह क्यों जानना चाहते हैं? काम करने के बाद, मैंने इसे दोबारा देखने की जहमत नहीं उठाई। मेरी परियोजना बहुत सारे विज़ुअलाइज़ेशन को आकर्षित करने के लिए थी, उपरोक्त कोड के साथ, काम का प्रवाह सुव्यवस्थित था।
हुलिन

1

यह मेरे लिए काम करता है:

प्रत्येक श्रृंखला के लिए, एक यादृच्छिक आरजीबी रंग जनरेटर का उपयोग करें

c = color[np.random.random_sample(), np.random.random_sample(), np.random.random_sample()]

मुझे नहीं पता कि आपका रंग चर क्या है, लेकिन आपके दृष्टिकोण का उपयोग करके ऐसा कुछ करना संभव है plt.scatter(your values to the graph, color= (np.random.random_sample(), np.random.random_sample(), np.random.random_sample()) ):। आपने RGB जनरेटर का उल्लेख किया और आपने RGB सूची घोषित की, जनरेटर '()' के बीच घोषित किए गए हैं
जोएल कार्नेइरो

0

बड़े डेटासेट और रंगों की सीमित संख्या के लिए MUCH का तेज़ समाधान पंडों और ग्रुपबी फ़ंक्शन का उपयोग है:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time


# a generic set of data with associated colors
nsamples=1000
x=np.random.uniform(0,10,nsamples)
y=np.random.uniform(0,10,nsamples)
colors={0:'r',1:'g',2:'b',3:'k'}
c=[colors[i] for i in np.round(np.random.uniform(0,3,nsamples),0)]

plt.close('all')

# "Fast" Scatter plotting
starttime=time.time()
# 1) make a dataframe
df=pd.DataFrame()
df['x']=x
df['y']=y
df['c']=c
plt.figure()
# 2) group the dataframe by color and loop
for g,b in df.groupby(by='c'):
    plt.scatter(b['x'],b['y'],color=g)
print('Fast execution time:', time.time()-starttime)

# "Slow" Scatter plotting
starttime=time.time()
plt.figure()
# 2) group the dataframe by color and loop
for i in range(len(x)):
    plt.scatter(x[i],y[i],color=c[i])
print('Slow execution time:', time.time()-starttime)

plt.show()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.