2017-07-08 84 views
1

我需要在matplotlib中繪製垂直散射圖,但我在matplotlib.org/examples或StackOverflow中找不到任何東西。如何僅使用matplotlib繪製垂直散射圖

我嘗試了一些我自己的東西,但我缺少抖動。對於具有相同(或非常相似)Y分量的點,抖動會稍微改變X分量,因此它們不會重疊。有什麼我可以使用或將不得不手動更改x組件?

import numpy as np 
from matplotlib import pyplot as plt 

x = np.array([1,2,3]) 
l = ['A','B','C'] 
a = np.array([2,2,3]) 
b = np.array([3,3,4]) 
c = np.array([7,7,5]) 
d = (np.array(a) + np.array(b) + np.array(c))/3 

plt.subplot(111) 
plt.margins(0.2) 
plt.xticks(x,l) 
plt.plot(x, a, 'ro', label='a') 
plt.plot(x, b, 'ro', label='b') 
plt.plot(x, c, 'ro', label='c') 
plt.plot(x, d, 'k_', markersize=15, label='avg') 
plt.tight_layout() 
plt.savefig('vertical_scatter') 
plt.close() 

這給了我以下

enter image description here

我發現這對Seaborn

enter image description here

這是我想要什麼,但只使用matplotlib。

+0

我想建議你提到要「保持它只是matplotlib」你的問題。 –

+0

是不是你的Matplotlib例子與預期的情節做同樣的事情? –

+0

人們經常在不需要的情況下使用seaborn,但在這種情況下,它似乎絕對合適,@ YLuo現在刪除的答案實際上工作得很好。就目前而言,這回答了這個問題,我實際上很想回避這個問題。如果您不想使用seaborn,請在您的問題中明確說明您要使用什麼以及爲什麼。清楚說明你的意思是「抖動」。 – ImportanceOfBeingErnest

回答

3

抖動僅使用matplotlib的例子如下。這個想法基本上是爲x值添加一些隨機噪聲。

import numpy as np 
import matplotlib.pyplot as plt 

data = np.random.rayleigh(scale=1, size=(30,4)) 
labels = list("ABCD") 
colors = ["crimson", "purple", "limegreen", "gold"] 

width=0.4 
fig, ax = plt.subplots() 
for i, l in enumerate(labels): 
    x = np.ones(data.shape[0])*i + (np.random.rand(data.shape[0])*width-width/2.) 
    ax.scatter(x, data[:,i], color=colors[i], s=25) 
    mean = data[:,i].mean() 
    ax.plot([i-width/2., i+width/2.],[mean,mean], color="k") 

ax.set_xticks(range(len(labels))) 
ax.set_xticklabels(labels) 

plt.show() 

enter image description here

1

就像我在我的評論中提到,你可以根據鄰近的y點的距離,卻將x值。較小的距離應映射到較大的x移。這可以用對數或其他功能來完成。

import numpy as np 
import matplotlib.pyplot as plt 

n = 100 
y = np.random.random(n) 
x = np.ones(n) 
x0 = x[0] 

y = np.sort(y) 
dist = np.diff(y) # has one entry less than y 
dist = np.hstack([dist, np.median(dist)]) # add random value to match shapes 
x = np.log(dist) 
x = (x - np.min(x))/(np.max(x) - np.min(x)) # mapped to range from 0 to 1 
x = x0 + 0.5*(x - 0.5) # mapped to range from x0-1/4 to x0+1/4 

plt.scatter(x,y) 
plt.scatter(x+1,y) 
plt.scatter(x+2,y) 

plt.show() 

enter image description here