2016-05-16 39 views
0

我希望橢圓的邊緣顏色是第三個變量的函數。我們假設第三個變量稱爲通量。如果變量'flux'的值很高,我希望橢圓的邊緣顏色是深藍色,如果值很低,我希望顏色變成黃色。任何中間值都應該是這些顏色的混合。我希望這個顏色漸變在最高和最低值的圖的z軸上可見。我試過指向這個鏈接Matplotlib scatterplot; colour as a function of a third variable,但這似乎不適用於我的情況。我讀從文本文件,它看起來像這樣繪製橢圓所需的參數:橢圓的邊緣顏色作爲第三個變量的函數

149.20562 2.29594 0.00418 0.00310 83.40 1.15569 

149.23158 1.99783 0.00437 0.00319 90.30 3.46331 

149.23296 2.45440 0.00349 0.00264 120.30 2.15457 

第五欄是基於名爲「流量」上的顏色漸變,必須繪製列。

這是我的嘗試的一個例子。

import matplotlib.pyplot as plt 
import numpy as np 
import math 
import astropy.io.ascii as asciitable 
from matplotlib.patches import Ellipse 
ax = plt.gca() 
path="https://stackoverflow.com/users/xxxx/Desktop/" 
plt.xlim([149,151.3]) 
plt.ylim([1,3.3]) 
fw=open(path + 'data_plot.txt', 'r') 
data = asciitable.read(path+ "data_plot.txt") 
np.array(data) 
for i in range(len(data)): 
    ra,dec,maj,minor,ang,flux =data[i][0],data[i][1],data[i][2],data[i][3],data[i][4],data[i][5] 
    ellipse = Ellipse(xy=(ra, dec), width=maj, height=minor, angle=ang, edgecolor=flux, lw=3, fc='None') 
    ax.add_patch(ellipse) 


plt.xlabel('Right Ascention') 
plt.ylabel('Declination') 
plt.title('abc') 
plt.savefig(path+'abc.eps') 

正如所料,這沒有奏效。這是我的錯誤日誌。

runfile('/users/vishnu/.spyder2-py3/radio_sources.py', wdir='/users/vishnu/.spyder2-py3') 

 
    Traceback (most recent call last): 

    File "<ipython-input-695-a0011c0326f5>", line 1, in <module> 
    runfile('/users/vishnu/.spyder2-py3/radio_sources.py', wdir='/users/vishnu/.spyder2-py3') 

    File "https://stackoverflow.com/users/vishnu/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 699, in runfile 
    execfile(filename, namespace) 

    File "https://stackoverflow.com/users/vishnu/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 88, in execfile 
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace) 

    File "https://stackoverflow.com/users/vishnu/.spyder2-py3/radio_sources.py", line 63, in <module> 
    ellipse = Ellipse(xy=(ra, dec), width=maj, height=minor, angle=ang, edgecolor=flux, lw=3, fc='None') 

    File "https://stackoverflow.com/users/vishnu/anaconda3/lib/python3.5/site-packages/matplotlib/patches.py", line 1378, in __init__ 
    Patch.__init__(self, **kwargs) 

    File "https://stackoverflow.com/users/vishnu/anaconda3/lib/python3.5/site-packages/matplotlib/patches.py", line 111, in __init__ 
    self.set_edgecolor(edgecolor) 

    File "https://stackoverflow.com/users/vishnu/anaconda3/lib/python3.5/site-packages/matplotlib/patches.py", line 277, in set_edgecolor 
    self._edgecolor = colors.colorConverter.to_rgba(color, self._alpha) 

    File "https://stackoverflow.com/users/vishnu/anaconda3/lib/python3.5/site-packages/matplotlib/colors.py", line 376, in to_rgba 
    'to_rgba: Invalid rgba arg "%s"\n%s' % (str(arg), exc)) 

ValueError: to_rgba: Invalid rgba arg "1.15569" 
to_rgb: Invalid rgb arg "1.15569" 
cannot convert argument to rgb sequence 

回答

2

你只需要改變flux值成matplotlib顏色。我們可以使用一個顏色映射來做到這一點,或者在你的情況下,你可以使用flux來定義顏色,假設一些最小值和最大值。

由於黃色只是紅色和綠色的混合,所以我們可以使用1減去R和G通道的歸一化通量,並使用歸一化通量作爲RGB元組的B通道來製作matplotlib顏色。

# Change these based on your definition of a 'high' value and a 'low' value (or the min/max of the data) 
minflux = data[:][5].min() 
maxflux = data[:][5].max() 

for i in range(len(data)): 
    ra,dec,maj,minor,ang,flux =data[i][0],data[i][1],data[i][2],data[i][3],data[i][4],data[i][5] 

    # Normalise the flux value to the range 0-1 
    normflux = (flux - minflux)/(maxflux - minflux) 
    # RGB tuple. This will be yellow for min value and blue for max value 
    fluxcolor = (1.-normflux, 1.-normflux, normflux) 

    ellipse = Ellipse(xy=(ra, dec), width=maj, height=minor, angle=ang, edgecolor=fluxcolor, lw=3, fc='None') 
    ax.add_patch(ellipse) 

這裏有一個小例子,以檢查它的工作原理:

import matplotlib.pyplot as plt 
from matplotlib.patches import Ellipse 
import numpy as np 

fig,ax = plt.subplots(1) 

minflux = 0. 
maxflux = 10. 

for i in range(10): 

    flux = float(i) 

    normflux = (flux - minflux)/(maxflux - minflux) 
    fluxcolor = (1.-normflux, 1.-normflux, normflux) 

    ell = Ellipse(xy=(i+1,0.5), width=0.5, height=0.3, angle=90., edgecolor=fluxcolor, lw=3, fc='None') 

    ax.add_patch(ell) 

ax.set_xlim(0,11) 
plt.show() 

enter image description here


要還添加了一個彩條,也許是最簡單的方法使用顏色表,而不是我上面展示的方法。在這種情況下,我們還可以使用PatchCollection將所有橢圓添加到軸,然後將集合的陣列設置爲通量值以定義它們的顏色。

例如:

import matplotlib.pyplot as plt 
from matplotlib.patches import Ellipse 
import numpy as np 

import matplotlib.colors as colors 
from matplotlib.collections import PatchCollection 

# Define our colormap here. 
# Want red and green to be 1 at 0, and 0 at 1. Blue to be 0 at 0, and 1 at 1. 
cdict = {'red': ((0.0,1.0,1.0), 
        (1.0,0.0,0.0)), 
     'green': ((0.0,1.0,1.0), 
        (1.0,0.0,0.0)), 
     'blue': ((0.0,0.0,0.0), 
        (1.0,1.0,1.0)) 
     } 
# Use that dictionary to define the Linear SegmentedColormap 
YlBu = colors.LinearSegmentedColormap('YlBu',cdict) 

# Create figure 
fig,ax = plt.subplots(1) 

# Set the aspect ratio 
ax.set_aspect('equal') 

# We will populate these lists as we loop over our ellipses 
ellipses = [] 
fluxes = [] 

for i in range(9): 

    # Use i as a dummy value for our flux 
    flux = float(i) 

    # Store the fluxes. You have this already in your data array 
    fluxes.append(flux) 

    # Angle is in degrees 
    angle = float(i) * 45. 

    # Create the ellipse patch. Don't add to the axes yet 
    ell = Ellipse(xy=(i,2.), width=0.8, height=0.2, angle=angle) 

    # Just add it to this list 
    ellipses.append(ell) 

# Now, create a patch collection from the ellipses. 
# Turn off facecolor, and set the colormap to the one we created earlier 
pc = PatchCollection(ellipses,False,lw=3,cmap=YlBu,facecolor='None') 

# Set the color array here. 
pc.set_array(np.array(fluxes)) 

# Now we add the collection to the axes 
ax.add_collection(pc) 

# And create a colorbar 
fig.colorbar(pc,orientation='horizontal') 

# Set the axes limits 
ax.set_xlim(-1,9) 
ax.set_ylim(0,4) 

plt.show() 

enter image description here

+0

如何顯示在z軸的彩色地圖,這樣,如果有人看到的情節,他們知道,黃色表示低值和藍色表示更高的價值? – Vishnu

+0

我認爲使用PatchCollection並定義色彩映射更容易。看到我上面編輯的答案。 – tom

+0

這是一個很好解釋的答案。謝謝。 :) – Vishnu