2012-12-22 11 views
7

bạn có ý tưởng nào không, làm thế nào tôi có thể bin 3 mảng thành biểu đồ. mảng của tôi trông giống nhưCác biểu đồ phân tán 2D và 3D từ các mảng trong Python

Temperature = [4, 3, 1, 4, 6, 7, 8, 3, 1] 
Radius  = [0, 2, 3, 4, 0, 1, 2, 10, 7] 
Density  = [1, 10, 2, 24, 7, 10, 21, 102, 203] 

Và cốt truyện 1D nên xem xét:

Density 

    |   X 
10^2-|    X 
    |  X 
10^1-| 
    | X 
10^0-| 
    |___|___|___|___|___ Radius 
     0 3.3 6.6 10 

Và âm mưu 2D nên (định tính) như sau:

Density 

    |   2  | | 
10^2-|  11249  | | 
    |  233   | | Radius 
10^1-| 12   | | 
    | 1    | | 
10^0-| 
    |___|___|___|___|___ Temperature 
     0 3 5 8 

Vì vậy, tôi muốn bin một hoặc hai trường có python/numpy và sau đó vẽ chúng để phân tích sự tương ứng của chúng.

+0

Tôi chắc chắn muốn khuyên bạn nên gói matplotlib - sử dụng rằng bạn * * có thể viết mã của bạn để vẽ cả hai biểu đồ đó - (http://matplotlib.org/examples/axes_grid/scatter_hist.html) – danodonovan

Trả lời

11

Tại đây, nó tuân theo hai chức năng: hist2d_bubblehist3d_bubble; mà có thể phù hợp cho mục đích của bạn:

enter image description here

import numpy as np 
import matplotlib.pyplot as pyplot 
from mpl_toolkits.mplot3d import Axes3D 


def hist2d_bubble(x_data, y_data, bins=10): 
    ax = np.histogram2d(x_data, y_data, bins=bins) 
    xs = ax[1] 
    ys = ax[2] 
    points = [] 
    for (i, j), v in np.ndenumerate(ax[0]): 
     points.append((xs[i], ys[j], v)) 

    points = np.array(points) 
    fig = pyplot.figure() 
    sub = pyplot.scatter(points[:, 0],points[:, 1], 
         color='black', marker='o', s=128*points[:, 2]) 
    sub.axes.set_xticks(xs) 
    sub.axes.set_yticks(ys) 
    pyplot.ion() 
    pyplot.grid() 
    pyplot.show() 
    return points, sub 


def hist3d_bubble(x_data, y_data, z_data, bins=10): 
    ax1 = np.histogram2d(x_data, y_data, bins=bins) 
    ax2 = np.histogram2d(x_data, z_data, bins=bins) 
    ax3 = np.histogram2d(z_data, y_data, bins=bins) 
    xs, ys, zs = ax1[1], ax1[2], ax3[1] 
    smart = np.zeros((bins, bins, bins),dtype=int) 
    for (i1, j1), v1 in np.ndenumerate(ax1[0]): 
     if v1 == 0: 
      continue 
     for k2, v2 in enumerate(ax2[0][i1]): 
      v3 = ax3[0][k2][j1] 
      if v1 == 0 or v2 == 0 or v3 == 0: 
       continue 
      num = min(v1, v2, v3) 
      smart[i1, j1, k2] += num 
      v1 -= num 
      v2 -= num 
      v3 -= num 
    points = [] 
    for (i, j, k), v in np.ndenumerate(smart): 
     points.append((xs[i], ys[j], zs[k], v)) 
    points = np.array(points) 
    fig = pyplot.figure() 
    sub = fig.add_subplot(111, projection='3d') 
    sub.scatter(points[:, 0], points[:, 1], points[:, 2], 
       color='black', marker='o', s=128*points[:, 3]) 
    sub.axes.set_xticks(xs) 
    sub.axes.set_yticks(ys) 
    sub.axes.set_zticks(zs) 
    pyplot.ion() 
    pyplot.grid() 
    pyplot.show() 
    return points, sub 

Hai con số trên được tạo ra sử dụng:

temperature = [4, 3, 1, 4, 6, 7, 8, 3, 1] 
radius  = [0, 2, 3, 4, 0, 1, 2, 10, 7] 
density  = [1, 10, 2, 24, 7, 10, 21, 102, 203] 
import matplotlib 
matplotlib.rcParams.update({'font.size':14}) 

points, sub = hist2d_bubble(radius, density, bins=4) 
sub.axes.set_xlabel('radius') 
sub.axes.set_ylabel('density') 

points, sub = hist3d_bubble(temperature, density, radius, bins=4) 
sub.axes.set_xlabel('temperature') 
sub.axes.set_ylabel('density') 
sub.axes.set_zlabel('radius') 

liên quan:

Howto bin series of float values into histogram in Python?

How to correctly generate a 3d histogram using numpy or matplotlib built in functions in python?

2D histogram with Python

+0

@tcaswell Tôi thấy quan điểm của bạn! Tôi đã cập nhật câu trả lời chỉ giữ âm mưu bong bóng! –

+2

Cảm ơn. Tôi đã lấy lại -1 và xóa các bình luận không áp dụng hiện tại của mình. Có một dòng hơi tinh tế của thao tác dữ liệu được chấp nhận là gì và cái gì không. Nếu bạn có một phương pháp _systematic_ dịch chuyển chúng (nói rằng bạn biết bạn chỉ nên lấy dữ liệu số nguyên và bạn định hình lại chúng thành hình xoắn ốc) nó sẽ là ok, nhưng việc thêm _random_ shift thì không. Sử dụng quy mô log là ok, bằng cách sử dụng một biến đổi tùy ý trên các trục của bạn thì không. Về cơ bản, nên không thể đảo ngược và thông thường. – tacaswell

1

đây là phiên bản 2D xương của mã Castro ở trên. Nó chỉ đơn giản là vẽ giá trị trung bình tại mỗi toạ độ x, y. Điều này có thể được vẽ bằng cách sử dụng imshow nhưng cách tiếp cận của Castro làm cho một âm mưu phân tán nhiều hơn.

from matplotlib import pyplot as plt 
import numpy as np 

# make some x,y points and z data that needs to be averaged and plotted 
x = [1,1,1,2,2,2,2,3,4,4,4,4] 
y = [1,1,1,2,2,2,2,3,4,4,4,4] 
z = [1,1,1,2,2,3,3,4,4,4,5,5] 
xbins, ybins = int(max(x)), int(max(y)) 
rng = [[1, xbins+1], [1, ybins+1]] 
bins = [xbins,ybins] 

# get the sum of weights and sum of occurrences (their division gives the mean) 
H, xs, ys =np.histogram2d(x, y, weights=z, bins=bins, range=rng) 
count, _, _ =np.histogram2d(x, y, bins=bins, range=rng) 

# get the mean value of each x,y point 
count = np.ma.masked_where(count==0,count) 
H = np.ma.masked_where(H==0,H) 
H/=count 

# separate the H matrix into x,y,z arrays (and discard zero values) 
points = [] 
for (i, j),v in np.ndenumerate(H): 
    if v: points.append((xs[i], ys[j], v)) 
points = np.array(points) 

# plot the data 
fig = plt.figure() 
cm = plt.cm.get_cmap('hot') 
p = plt.scatter(points[:, 0], points[:, 1], c=points[:, 2], cmap=cm) 
plt.colorbar(p).set_label('avg. z value') 
plt.grid() 
plt.show() 

Tất cả các x trùng lặp, các điểm y hiện nay giảm xuống còn một bộ duy nhất và giá trị z của họ đã được trung bình:

averaged z value of duplicated x,y coordinates