2015-05-14 24 views
27

Đối với một dự án tôi đang thực hiện một số ô phân tán 3D với ba phép chiếu tương ứng bên dưới nó. Tôi sử dụng các màu khác nhau để chỉ ra tham số thứ tư. Đầu tiên tôi âm mưu dữ liệu với một màu nhất định và sau đó tôi overplot rằng với dữ liệu khác với một màu khác nhau, vì vậy mà cuối cùng thì thứ tự là như vậy mà tôi có thể nhìn thấy tất cả mọi thứ như tôi muốn:Màu sắc bị mất trong âm mưu phân tán 3D Matplotlib

This is what I want!

Trong bắt đầu điều này làm việc tốt, nhưng khi tôi cố gắng làm điều tương tự với dữ liệu hơi khác nhau, màu sắc có được điều sai lầm. Những màu sắc hiển thị trong dự là những cái đúng, nhưng một số người trong số họ mất tích trong cốt truyện 3D vì vậy họ không phù hợp nữa:

Colors messed up :(

Khi tôi xoay cốt truyện 3D một cách hài hước, các màu sắc được bình phục và tôi có thể nhìn thấy chúng khi chúng được coi như là:

Funny rotation

Tuy nhiên, tôi không muốn một âm mưu 3D mà được quay một cách buồn cười, bởi vì các trục được điều sai lầm và nó không thể đọc nó đúng như thế.

Tôi đã tìm thấy một giải pháp cho vấn đề ở đây: plotting 3d scatter in matplotlib. Về cơ bản nó nói rằng tôi nên thay thế ax.scatter của tôi (X, Y) với ax.plot (X, Y, 'o'). Khi tôi làm điều này, các màu sắc được thể hiện theo cách mà chúng được cho là, nhưng cốt truyện thì phức tạp hơn và xấu hơn theo cách này. Về cơ bản tôi chỉ muốn có thể làm điều này với một âm mưu phân tán.

Có ai biết cách giải quyết vấn đề này không?

Dưới đây là một ví dụ tối thiểu là mã của tôi, vì chỉ có hai màu sắc:

from mpl_toolkits.mplot3d import art3d 
import numpy as np 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
from matplotlib import gridspec 

art3d.zalpha = lambda *args:args[0] 

numcols = 20 
percentage = 50 

def load(Td, pc): 
    T = np.load(str(pc) + 'pctTemperaturesTd=' + str(Td) + '.npy') 
    D = np.load(str(pc) + 'pctDensitiesTd=' + str(Td) + '.npy') 
    CD = np.load(str(pc) + 'pctColDensitiesTd=' + str(Td) + '.npy') 
    return T, D, CD 

def colors(ax): 
    colors = np.zeros((numcols, 4)) 
    cm = plt.get_cmap('gist_rainbow') 
    ax.set_color_cycle([cm(1.*i/numcols) for i in range(numcols)]) 
    for i in range(numcols): 
     color = cm(1.*i/numcols) 
     colors[i,:] = color 
    return colors 

# LOAD DATA 
T10, D10, CD10 = load(10, percentage) 
T200, D200, CD200 = load(200, percentage) 

# 3D PLOT 
fig = plt.figure(1) 
gs = gridspec.GridSpec(4, 4) 

ax = fig.add_subplot(gs[:-1,:-1], projection='3d') 
colours = colors(ax) 

ax.plot(T200/100., np.log10(D200), np.log10(CD200), '*', markersize=10,color=colours[10], mec = colours[10], label='Td = 200', alpha=1) 
ax.plot(T10/100., np.log10(D10), np.log10(CD10), '*', markersize=10,color=colours[0], mec = colours[0], label='Td = 10', alpha=1) 

ax.set_xlabel('\nTg/100', fontsize='x-large') 
ax.set_ylabel('\nlog(nH)', fontsize='x-large') 
ax.set_zlabel('\nlog(colDen)', fontsize='x-large') 
ax.set_xlim(0,5) 
#ax.set_zlim(0,) 
ax.set_ylim(2,6) 

# PROJECTIONS 

# Tg, nH 
ax2 = fig.add_subplot(gs[3,0]) 

ax2.scatter(T200/100., np.log10(D200), marker='*', s=10, color=colours[10], label='Td = 200', alpha=1, edgecolor=colours[10]) 
ax2.scatter(T10/100., np.log10(D10), marker='*', s=10, color=colours[0], label='Td = 10', alpha=1, edgecolor=colours[0]) 

ax2.set_xlabel('Tg/100') 
ax2.set_ylabel('log(nH)') 
ax2.set_xlim(0,6) 

# Tg, colDen 
ax3 = fig.add_subplot(gs[3,1]) 

ax3.scatter(T200/100., np.log10(CD200), marker='*', s=10, color=colours[10], label='Td = 200', alpha=1, edgecolor=colours[10]) 
ax3.scatter(T10/100., np.log10(CD10), marker='*', s=10, color=colours[0], label='Td = 10', alpha=1, edgecolor=colours[0]) 

ax3.set_xlabel('Tg/100') 
ax3.set_ylabel('log(colDen)') 
ax3.set_xlim(0,6) 

# nH, colDen 
ax4 = fig.add_subplot(gs[3,2]) 

ax4.scatter(np.log10(D200), np.log10(CD200), marker='*', s=10, color=colours[10], label='Td = 200', alpha=1, edgecolor=colours[10]) 
ax4.scatter(np.log10(D10), np.log10(CD10), marker='*', s=10, color=colours[0], label='Td = 10', alpha=1, edgecolor=colours[0]) 

ax4.set_xlabel('log(nH)') 
ax4.set_ylabel('log(colDen)') 

# LEGEND 
legend = fig.add_subplot(gs[:,3]) 

text = ['Td = 10', 'Td = 20', 'Td = 30', 'Td = 40', 'Td = 50', 'Td = 60', 'Td = 70', 'Td = 80', 'Td = 90', 'Td = 100', 'Td = 110', 'Td = 120', 'Td = 130', 'Td = 140', 'Td = 150', 'Td = 160', 'Td = 170', 'Td = 180', 'Td = 190', 'Td = 200'] 

array = np.arange(0,2,0.1) 
for i in range(len(array)): 
    legend.scatter(0, i, marker='*', s=100, c=colours[numcols-i-1], edgecolor=colours[numcols-i-1]) 
    legend.text(0.3, i-0.25, text[numcols-i-1]) 
    legend.set_xlim(-0.5, 2.5) 
    legend.set_ylim(0-1, i+1) 

legend.axes.get_xaxis().set_visible(False) 
legend.axes.get_yaxis().set_visible(False) 

gs.tight_layout(fig) 

plt.show() 
+0

Bạn có thể chia sẻ mã không? Bạn có thể chỉ định cấu trúc dữ liệu được sử dụng hay đại diện cho hình dạng dữ liệu bạn đang sử dụng không? Hơn nữa, hai tập dữ liệu bạn đang sử dụng khác nhau như thế nào (có một số tính năng được chuyển đổi trong một tập dữ liệu so với bộ dữ liệu khác không? - điều này sẽ giải thích sự xuất hiện của màu đỏ khi bạn xoay biểu đồ .. nhưng nó vẫn còn lạ)? – kasparg

+0

Tôi đã bao gồm mã của mình. Các tập dữ liệu chỉ là mảng cố định, phần thứ hai phải là tập hợp con của tập đầu tiên, có nghĩa là nó chỉ bao gồm các điểm cũng xuất hiện trong phần đầu tiên nhưng chúng chỉ là ít hơn. Ngoài ra không có gì thay đổi. Tôi nghĩ rằng đó là một lỗi, tôi thấy không có cách nào để thay đổi thứ tự mà nó hiển thị dữ liệu của tôi. Bây giờ tôi chỉ giải quyết nó bằng cách sử dụng 'cốt truyện' thay vì 'phân tán' sau khi tất cả. – Nikki

+0

Điều đầu tiên tôi xem xét là ['zorder'] (http://matplotlib.org/examples/pylab_examples/zorder_demo.html). – kwinkunks

Trả lời

1

Thay vì sử dụng ax.plot(x,y, 'o') thử ax.plot(x,y,'.') hoặc ax.plot(x,y,'*'. 'o' đang chỉ định marker để sử dụng và điểm đánh dấu 'o' là một vòng tròn lớn chứa đầy, đó là lý do tại sao cốt truyện của bạn trông xấu xí.

Các vấn đề liên quan