2017-11-11 164 views
0

我迷失在matplotlib中使用的不同方法。色條和日期時間軸刻度的散點圖

我想創建一個顏色編碼的散點圖,在x軸的側面和日期時間使用顏色條。

但取決於我如何定義我的ax,我得到不同的錯誤。 下面是我的核心代碼:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 
import matplotlib.cm as cm 
import matplotlib.dates as mdates 

#.....loading files etc. 

norm = mcolors.Normalize(vmin=0,vmax=1000) 
timerange = pd.date_range(start='2015-01-01', end='2016-01-01', freq='30D') 

### PLOTTING 
fig = plt.figure(figsize=(6.,5)) 
ax = fig.add_subplot(111) 

for Af in Afiles: 
    for index, row in Af.iterrows(): 
     time = pd.to_datetime(row['date'], format="%Y-%m-%d") 
     plt.scatter(time, row['A'], c=row['z'], norm=norm, cmap=colormap,edgecolor='k', lw=0.8, s=80) 

plt.xticks(timerange, rotation=90) 
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d/%m/%Y")) 
plt.xlabel('Time', fontsize=11, color='k') 

clb = fig.colorbar(ax)  
clb.ax.set_title('Value', y=-0.125, fontsize=11) 
clb.ax.invert_yaxis() 

fig.tight_layout() 

這將產生AttributeError: 'AxesSubplot' object has no attribute 'autoscale_None'

但如果我指定我ax的散點圖,這樣我可以讓我的顏色編碼的工作,然後我有麻煩軸格式化程序。 代替ax = plt.scatter生成AttributeError: 'PathCollection' object has no attribute 'xaxis'

我怎樣才能同時具有彩條和格式化的軸蜱?

回答

1

不要叫分散ax。 (這會覆蓋已存在的軸ax。)
色條期望作爲第一個參數的ScalarMappable(例如散點圖)。由於散射都是標準化的,可以從循環使用,

norm = plt.Normalize(...) 
for bla in blubb: 
    scatter = plt.scatter(..., norm=norm) 

然後,

clb = fig.colorbar(scatter) 

其餘部分應保持不變。

+0

當然!傻我,謝謝。這很尷尬。 – durbachit

0

其基本思想是您需要爲顏色條添加額外的軸。

很難知道這是否完全匹配,因爲您尚未提供數據的工作示例。但這至少可以作爲模板。

首先,一些示例數據:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 
import matplotlib.cm as cm 
import matplotlib.dates as mdates 
from mpl_toolkits.axes_grid1 import make_axes_locatable 

vmin = 0 
vmax = 1000 
timerange = pd.date_range(start='2015-01-01', end='2016-01-01', freq='30D') 
N = len(timerange) 

data = np.random.randint(vmin, vmax, size=N) 
# z contains the colorbar values for each point 
cmap = plt.get_cmap('Reds') 
z = [cmap((x-vmin)/(vmax-vmin))[:3] for x in data] 
df = pd.DataFrame({"value":data, "datetime":timerange, "z":z}) 

現在劇情:

fig = plt.figure(figsize=(6.,5)) 
ax = fig.add_subplot(111) 

plt.scatter(x=df.datetime.values, y=df.value.values, c=df.z) 

ax.set_xticklabels(timerange, rotation=90) 
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d/%m/%Y")) 
ax.set_xlabel('Time') 

現在加上彩條:

norm = mcolors.Normalize(vmin=vmin,vmax=vmax) 
m = cm.ScalarMappable(cmap='Reds', norm=norm) 
m.set_array([(x-vmin)/(vmax-vmin) for x in df.value.values]) 

divider = make_axes_locatable(ax) 
cax = divider.append_axes("right", size="5%", pad=0.1) 
clb = plt.colorbar(m, cax=cax) 

scatter plus colormap

+0

對不起,爲了澄清,這將如何工作我的循環?當我沒有單個數據框但很多時,如何設置標量可映射?對於許多不同數值範圍的許多數據幀,我需要一個通用的色條(通用色彩方案)。 請注意,只要我保留數字x軸,我的彩條的代碼(當設置'ax = plt.scatter'時)就完美地工作。當我開始使用軸格式化時出現問題。 – durbachit

+0

如果你需要一個通用的顏色條,那麼就顏色條而言你沒有很多不同的範圍,你只有一個。選擇完整數據集的最小值和最大值以設置可映射。循環可以保持不變,我只是爲一個數據框提供示例數據來給出一個工作示例。 –

+1

說了這麼多之後,它看起來像ImportanceOfBeingErnest的答案更簡單,我將首先承認我對Matplotlib的優雅沒有很好的理解。嘗試一下他的方法! –

相關問題