Dla projektu tworzę kilka wykresów rozproszenia 3D z trzema odpowiednimi rzutami pod nim. Używam różnych kolorów, aby wskazać czwarty parametr. Najpierw wykreślić dane o określonym kolorze, a potem overplot że z innymi danymi o innym kolorze, tak że w końcu kolejność jest taka, że widzę wszystko jak chcę:Kolory zagubione w Matplotlib 3D wykres rozproszenia
W zaczynało się to dobrze, ale kiedy próbuję zrobić to samo z nieco innymi danymi, kolory się zawiodły. Przedstawione kolory w projekcjach są właściwe, ale niektóre z nich brakuje w działce 3D więc nie pasują już:
Kiedy obrócić wykres 3D w zabawny sposób, kolory są odzyskiwane i widzę je jako oni powinni być:
jednak nie chcę wykres 3D, który obraca się w zabawny sposób, ponieważ osie się pokręcić i to nie można go tak właściwie odczytać.
Znalazłem jedno rozwiązanie problemu tutaj: plotting 3d scatter in matplotlib. W zasadzie mówi, że powinienem zamienić mój ax.scatter (X, Y) na ax.plot (X, Y, "o"). Kiedy to robię, kolory są pokazywane tak, jak powinny, ale fabuła jest w ten sposób dużo bardziej powikłana i brzydsza. Po prostu chcę to zrobić z działką rozproszoną.
Czy ktoś wie, jak rozwiązać ten problem?
Oto minimalny przykład mojego kodu, tylko dwa kolory:
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()
Czy możesz udostępnić kod? Czy możesz określić używane struktury danych lub reprezentować kształt danych, których używasz? Co więcej, jak różne są te dwa zestawy danych, których używasz (czy niektóre funkcje są transponowane w jednym zestawie danych w porównaniu do innych? - to wyjaśniałoby wygląd czerwieni podczas obracania wykresów ... ale wciąż jest dziwne)? – kasparg
Zawarłem mój kod. Zbiory danych są po prostu numpy tablicami, druga powinna być podzbiorem pierwszej, więc można powiedzieć, że składa się ona tylko z punktów, które pojawiają się również w pierwszej, ale są one po prostu mniej. Poza tym nic się nie zmienia. Myślę, że to błąd, nie znalazłem sposobu na zmianę kolejności wyświetlania moich danych. Na razie jednak rozwiązałem go, używając "fabuły" zamiast "rozproszenia". – Nikki
Pierwszą rzeczą, na którą patrzę, jest ['zorder'] (http://matplotlib.org/examples/pylab_examples/zorder_demo.html). – kwinkunks