Pieņemsim, ka man ir trīs datu kopas:
X = [1,2,3,4]
Y1 = [4,8,12,16]
Y2 = [1,4,9,16]
Es varu izveidot izkliedes diagrammu:
from matplotlib import pyplot as plt
plt.scatter(X,Y1,color='red')
plt.scatter(X,Y2,color='blue')
plt.show()
Kā to izdarīt ar 10 kopām?
Es to meklēju un nevarēju atrast nekādu atsauci uz to, ko es jautāju.
Rediģēt: mana jautājuma precizēšana (cerams)
Ja es izsaucu izkliedi vairākas reizes, es varu iestatīt tikai vienu un to pašu krāsu katrai izkliedei. Zinu arī, ka varu manuāli iestatīt krāsu masīvu, bet esmu pārliecināts, ka ir kāds labāks veids, kā to izdarīt. Mans jautājums ir šāds: "Kā es varu automātiski izkliedēt savas vairākas datu kopas, katrai no tām piešķirot citu krāsu.
Ja tas palīdz, es varu viegli piešķirt unikālu numuru katrai datu kopai.
Es nezinu, ko jūs domājat ar 'manuāli'. Jūs varat viegli izvēlēties krāsu karti un izveidot krāsu masīvu:
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)
Vai arī varat izveidot savu krāsu ciklleri, izmantojot itertools.cycle
un norādot krāsas, kuras vēlaties izmantot cilpā, un izmantojot next
, lai iegūtu vajadzīgo krāsu. Piemēram, ar 3 krāsām:
import itertools
colors = itertools.cycle(["r", "b", "g"])
for y in ys:
plt.scatter(x, y, color=next(colors))
Ja tā padomā, varbūt tīrāk ir neizmantot zip
arī ar pirmo:
colors = iter(cm.rainbow(np.linspace(0, 1, len(ys))))
for y in ys:
plt.scatter(x, y, color=next(colors))
Parasts veids, kā matplotlib programmā uzzīmēt laukumus ar dažādu krāsu punktiem, ir kā parametru nodot krāsu sarakstu.
Piem:
import matplotlib.pyplot
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=['red','green','blue'])
Ja jums ir saraksts ar sarakstiem un vēlaties, lai tie būtu iekrāsoti katrā sarakstā. Manuprāt, viselegantākais veids ir tas, ko ierosināja @DSM, vienkārši izveidojiet cilpu, vairākkārt izsaucot izkliedi.
Bet, ja kāda iemesla dēļ vēlaties to izdarīt tikai ar vienu izsaukumu, varat izveidot lielu krāsu sarakstu, izmantojot saraksta izpratni un mazliet grīdas dalīšanu:
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])]
Šis jautājums ir nedaudz sarežģīts pirms 2013. gada janvāra un matplotlib 1.3.1 (2013. gada augusts), kas ir vecākā stabilā versija, ko var atrast matpplotlib vietnē. Bet pēc tam tas ir diezgan triviāli.
Jo pašreizējā matplplotlib.pylab.scatter
versija atbalsta piešķiršanu: krāsu nosaukuma virknes masīvam, float skaitļa masīvam ar krāsu karti, RGB vai RGBA masīvam.
Šī atbilde ir veltīta @Oxinabox'nebeidzamajai aizrautībai labot 2013. gada versiju 2015. gadā.
Jums ir divas iespējas izmantot izkliedes komandu ar vairākām krāsām vienā izsaukumā.
kā pylab.scatter
komanda atbalsta izmantot RGBA masīvu, lai veiktu jebkuru krāsu;
Kods ir arī iedvesmojies no pyplot.scatter
avota koda, es tikai dublēju to, ko dara scatter, neizmantojot to, lai zīmētu.
Komanda pyplot.scatter
atgriež PatchCollection
objektu, failā "matplotlib/collections.py" Collection
klases privātais mainīgais _facecolors
un metode set_facecolors
.
Tātad, kad vien jums ir izkliedes punkti, ko zīmēt, jūs varat to izdarīt:
# 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()