2015-11-27 28 views
-2

我已經閱讀了問題Matplotlib: avoiding overlapping datapoints in a "scatter/dot/beeswarm" plot和問題Adding a scatter of points to a boxplot using matplotlib但是我想產生像這樣的,其中R產生的圖:Matplotlib:非隨機抖動

R plots http://www.cbs.dtu.dk/~eklund/beeswarm/beeswarm_example_02.png

Here是用於這些數字的代碼。

我想用matplotlib來做,但到目前爲止,我只能設法使用np.random.normal(i, 0.05)。點彼此分開,但我想要他們訂購。

This answer做了類似於我想要的東西,但我的數據是非常接近但是不同的浮點數,因此groupby函數不起作用,我想要點對稱於中心,如用上面示出的R生成的圖。

回答

1

由於在這個問題Matplotlib: avoiding overlapping datapoints in a "scatter/dot/beeswarm" plot編輯指出,我並沒有在一開始讀,有一個Python包的那種情節:

https://github.com/mgymrek/pybeeswarm

,絕對是包做了比下面的代碼好得多。

我修改了this answer的代碼來接受浮點數,我得到了一些與我想要的相似的東西。下面是代碼:

CA = [0,4,0,3,0,5] 
CB = [0,0,4,4,2,2,2,2,3,0,5] 
CC = [0.08423, 4.0078, 0.02936, 0.04862, 3.2105, 3.7796, 1.9974, 1.6986, 1.7443, 1.6615, 1, 1, 1] 

lists = [CA, CB, CC] 

x = [] 
y = [] 
for index1, my_list in enumerate(lists): 
    scores_bins = {} 
    for index2, score in enumerate(my_list): 
     binx = round(score, 1) 
     if binx not in scores_bins: 
      scores_bins[binx] = [] 
     scores_bins[binx].append(score) 

    for key, val in sorted(scores_bins.items()): 
     values = scores_bins[key] 
     points = len(values) 
     pos = 1 + index1 + (1 - points)/50. 
     for value in values: 
      x.append(pos) 
      y.append(value) 
      pos += 0.05 

plt.plot(x, y, 'o') 
plt.xlim((0,4)) 
plt.ylim((-1,6)) 

plt.show() 

但是,如果pos增加點多移動到右側,而不是從中心到右只是傳播和左...