ম্যাটপ্লোটিলেব বিছানা প্লটে প্রতিটি সিরিজের জন্য আলাদা রঙ নির্ধারণ করা


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
কি এখানে জিজ্ঞাসা? রঙ এছাড়াও একটি অ্যারে হতে পারে, তবে আপনি কেবল একাধিকবার কলঙ্ক ছড়িয়ে দিয়ে কী সমাধান করতে পারবেন না?
সেবার্গ

1
যদি আমি একাধিকবার স্ক্যাটারকে কল করি তবে আমি একই রঙগুলি পাই। আমি আমার প্রশ্ন আপডেট করব।
Yotam

উত্তর:


268

'ম্যানুয়ালি' বলতে কী বোঝাতে চেয়েছি তা আমি জানি না। আপনি একটি কালারম্যাপ চয়ন করতে পারেন এবং সহজেই রঙের অ্যারে তৈরি করতে পারেন:

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 টি রঙের ম্যাটপ্ল্লিটিব গ্রাফ

এটি ভাবতে আসুন, সম্ভবত এটি 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
@ ডেভিডরবিনসন: আপনি যদি দশটি নির্দিষ্ট করেন তবে তা নয়, যদিও আমি সাইক্লিংয়ের ধরণটি সেখানে উদ্দেশ্যকে পরাস্ত করতে সম্মত হয়েছি ..: ^)
ডিএসএম

অবিকল - তাহলে এটি কোনও চক্র নয় :)
ডেভিড রবিনসন

4
@ ম্যাক্রোকোসমে: আমার পক্ষে কাজ করে। plt.legend(['c{}'.format(i) for i in range(len(ys))], loc=2, bbox_to_anchor=(1.05, 1), borderaxespad=0., fontsize=11)উপরের নীচে যুক্ত করা আমাকে রঙগুলির সাথে একটি কিংবদন্তি দেয়।
ডিএসএম

আপনি কিছু রঙ এড়াতে চাইলে ইটারটুলস সলিউশনটি দুর্দান্ত। আমার ক্ষেত্রে যেহেতু ব্যাকগ্রাউন্ড কালো তাই আমি কালো এড়াতে চাই।
Fabrizio

50

ম্যাটপ্ল্লোলিবের বিভিন্ন রঙের পয়েন্ট সহ প্লট প্লট করার স্বাভাবিক উপায় হ'ল প্যারামিটার হিসাবে রঙগুলির একটি তালিকা পাস করা।

উদাহরণ:

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

3 রঙ

যখন আপনার তালিকাগুলির একটি তালিকা রয়েছে এবং আপনি তালিকা অনুযায়ী সেগুলি রঙিন করতে চান। আমি মনে করি সবচেয়ে মার্জিত উপায়টি হ'ল @ ডিএসএম দ্বারা প্রস্তাবিত, কেবল ছড়িয়ে ছিটিয়ে একাধিক কল করার জন্য একটি লুপ করুন।

তবে যদি কোনও কারণে আপনি কেবল একটি কল দিয়ে এটি করতে চেয়েছিলেন তবে আপনি একটি তালিকা বোঝার সাথে কিছুটা ফ্লোরিং বিভাগ সহ রঙের একটি বৃহত তালিকা তৈরি করতে পারেন:

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
হাই @ পেব্যাকএসি, এটি দেখানোর জন্য ধন্যবাদ, আমি আজ বিকেলে চেষ্টা করেছি এটি এ ক্ষেত্রে এটির কাজটি করার জন্য কিন্তু আমি কোনও সমাধান পাইনি তাই আমি প্রশ্নটি সম্পাদনা করে অন্য ব্যবহারকারীদের সতর্ক করেছিলাম। ধন্যবাদ!
জিএম

হাই @ জিএম, দুঃখিত আমি সমাধানটি চূড়ান্ত করার আগে কয়েকটি মন্তব্য পোস্ট করেছি, যা এখানে বর্ণিত হয়েছে: স্ট্যাকওভারফ্লো.com/q/51444364/7541421
পেব্যাক

1
আমি স্কেটার প্লটে প্রতিটি সিরিজের জন্য রঙগুলি নির্ধারণ করতে অন্য পদ্ধতি ব্যবহার করেছি। এখন এটি কাজ করে, দুর্ভাগ্যক্রমে আমি যখন আপনার ত্রুটিযুক্ত বারগুলির কথা বলি তখন আপনার মার্জিত সমাধান নিয়ে এগিয়ে যেতে পারিনি, তবুও আমি আপনার সুপার সহায়ক পোস্টের জন্য সত্যই কৃতজ্ঞ! চিয়ার্স!
পেব্যাকাক

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

এই প্রশ্নটি জানুয়ারী ২০১৩ এবং ম্যাটপ্ল্লিটিব ১.৩.১ (আগস্ট ২০১৩) এর আগে কিছুটা জটিল, আপনি ম্যাটપ્প্লটলিব ওয়েবসাইটে যে সর্বাধিক প্রাচীন স্থিতিশীল সংস্করণটি খুঁজে পেতে পারেন। তবে তারপরে এটি বেশ তুচ্ছ।

কারণ matplotlib.pylab.scatterসমর্থন কার্যকারিতার বর্তমান সংস্করণ : রঙের নাম স্ট্রিংয়ের অ্যারে, রঙের মানচিত্র সহ ভাসমান সংখ্যার অ্যারে, আরজিবি বা আরজিবিএর অ্যারে।

এই উত্তরটি ২০১৫ সালে আমার নিজের 2013 সংস্করণটি সংশোধন করার জন্য @ অক্সিনাবক্সের অন্তহীন আবেগকে উত্সর্গ করা হয়েছে।


আপনার একক কলে একাধিক রঙ সহ স্ক্রেটার কমান্ড ব্যবহারের দুটি বিকল্প রয়েছে।

  1. pylab.scatterকমান্ড সমর্থন হিসাবে আরজিবিএ অ্যারে ব্যবহার করুন আপনি যা রঙ চান তা করতে;

  2. ২০১৩ এর প্রথম দিকে, এটি করার কোনও উপায় নেই, যেহেতু কমান্ডটি কেবল পুরো স্ক্যাটার পয়েন্ট সংগ্রহের জন্য একক রঙকে সমর্থন করে। আমি যখন আমার 10000-লাইনের প্রকল্পটি করছিলাম তখন আমি এটিকে বাইপাস করার জন্য একটি সাধারণ সমাধান খুঁজে বের করি। সুতরাং এটি খুব কঠিন, তবে আমি এটি আকার, রঙ, আকার এবং স্বচ্ছ যাই হোক না কেন এটি করতে পারি। এই কৌশলটি পথ সংগ্রহ, লাইন সংগ্রহ আঁকার ক্ষেত্রেও প্রয়োগ করা যেতে পারে ....

কোডটি সোর্স কোড দ্বারাও অনুপ্রাণিত হয় 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()) )। আপনি একটি আরজিবি জেনারেটর উল্লেখ করেছেন এবং আপনি একটি আরজিবি তালিকা ঘোষণা করেছেন, '()' এর মধ্যে জেনারেটর ঘোষণা করা হয়েছে
জোয়েল কারনেইরো

0

বড় ডেটাসেট এবং সীমিত সংখ্যক রঙের জন্য একটি খুব দ্রুত সমাধান হ'ল পান্ডাস এবং গ্রুপবাই ফাংশন ব্যবহার:

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()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.