2017-07-24 58 views
1

我有一個hbar-由ColumnDataSource驅動,並在y軸上有分類標籤和兩個數字x軸。爲了在y軸上爲每個標籤設置兩組條形,我構建了兩個範圍(Things1=df.Thing.index + 1 - 0.2Things2=df.Thing.index + 1 + 0.2),並將兩個hbar-實例分別指定爲這些範圍中的一個。使用散焦hbar和ColumnDataSource逐個標籤

當且僅當ColumnDataSource中的Things1Things2範圍以預定義的偏移量1構造時,這給了我正確的佈局;否則,所有的標籤和條都會被一個條目所抵消。

我現在構建的情節的方式看起來是這樣的:

df = pandas.DataFrame([('Store', 'Juice', 3, 19.0), 
         ('Warehouse', 'Paint', 7, 21.0), 
         ('Store', 'Fruit', 2, 6.0), 
         ('Warehouse', 'Grass', 4, 15.0), 
         ('Store', 'Leaves', 9, 32.0)], 
         columns=('Storage', 'Thing', 'Quantity', 'Valueation')) 


source = bokeh.models.ColumnDataSource(dict(Quantity=df.Quantity, 
              Things1=df.Thing.index + 1 - 0.2, # Why +1 ? 
              Things2=df.Thing.index + 1 + 0.2, # Why +1 ? 
              Valueation=df.Valueation, 
              Storage=df.Storage)) 

plot = bokeh.plotting.figure(plot_width=800, plot_height=300, 
          y_range=list(df.Thing.unique()), 
          x_range=(0, df.Quantity.max() * 1.1)) 
plot.hbar(y='Things1', right='Quantity', height=0.3, alpha=0.7, source=source) 
plot.hbar(y='Things2', right='Valueation', height=0.3, alpha=1, source=source, 
      x_range_name="ValueationRange") 
plot.yaxis.axis_label = 'Thing' 
plot.xaxis.axis_label = 'Quantity' 
plot.extra_x_ranges = {"ValueationRange": 
         bokeh.models.Range1d(start=0, end=df.Valueation.max() * 1.1)} 
plot.add_layout(bokeh.models.LinearAxis(x_range_name="ValueationRange", 
             axis_label='Valueation'), 'above') 
bokeh.plotting.show(plot) 

Things1/2=df.Thing.index + 1 -/+ 0.2提供了正確的陰謀:

Correct plot

隨着Things1/2=df.Thing.index -/+ 0.2我得到

Wrong plot

我的猜測是這是由於不同的範圍是基於0或1的。這是一個簡單的問題,還是我做錯了?

回答

1

編輯原來,原始值(與真正的分類數據相反)與因子範圍的使用沒有記錄和未經測試。分類數據的處理將在0.12.7中改變,這將允許正確使用分類數據所需的功能 - 請參閱下面的bigreddots(lead bokeh dev)評論。

從單純的觀察來看,似乎分類範圍的默認行爲是將整數y值從1開始映射到類別。

如果初始化劇情對象後添加y_range,原始蜱暴露: plot no label

就像你提到的,它只是由於範圍。第一個繪製的數據序列從0開始,但從第一個標籤開始。您可以使用functickformatter設置偏移或將明確的y刻度映射到值,從而精確控制值和標籤之間的映射。

如果你看一個例子,如http://bokeh.pydata.org/en/latest/docs/gallery/categorical.html,你可以看到數據被映射到類別,但這是因爲y值是作爲因子本身輸入的。在你的例子中,你只是改變y軸,但抵消了你不能使用原始類別本身的值。

順便說一句: 編輯offset屬性可能不存在0.12.7因此可能最好不要依賴於它/假定它會存在。

看看文檔說默認的偏移量是0.所以我想你會想要一個-1的偏移量來解決這個問題。見http://bokeh.pydata.org/en/latest/docs/reference/models/ranges.html#bokeh.models.ranges.FactorRange.offset

import pandas 

import bokeh 
import bokeh.models, bokeh.plotting 

df = pandas.DataFrame([('Store', 'Juice', 3, 19.0), 
         ('Warehouse', 'Paint', 7, 21.0), 
         ('Store', 'Fruit', 2, 6.0), 
         ('Warehouse', 'Grass', 4, 15.0), 
         ('Store', 'Leaves', 9, 32.0)], 
         columns=('Storage', 'Thing', 'Quantity', 'Valueation')) 


source = bokeh.models.ColumnDataSource(dict(Quantity=df.Quantity, 
              Things1=df.Thing.index - 0.2, # Why +1 ? 
              Things2=df.Thing.index + 0.2, # Why +1 ? 
              Valueation=df.Valueation, 
              Storage=df.Storage)) 

plot = bokeh.plotting.figure(plot_width=800, plot_height=300, 
          y_range=list(df.Thing.unique()), 
          x_range=(0, df.Quantity.max() * 1.1)) 

plot.y_range.offset = -1 

plot.hbar(y='Things1', right='Quantity', height=0.3, alpha=0.7, source=source) 
plot.hbar(y='Things2', right='Valueation', height=0.3, alpha=1, source=source, 
      x_range_name="ValueationRange") 
plot.yaxis.axis_label = 'Thing' 
plot.xaxis.axis_label = 'Quantity' 
plot.extra_x_ranges = {"ValueationRange": 
         bokeh.models.Range1d(start=0, end=df.Valueation.max() * 1.1)} 
plot.add_layout(bokeh.models.LinearAxis(x_range_name="ValueationRange", 
             axis_label='Valueation'), 'above') 
bokeh.plotting.show(plot) 
+1

請注意categoricals的處理在明年背景虛化的釋放正在改變,而'offset'特性可完全移除。官方支持的提供分類座標的方法是使用實​​際類別,而不是嘗試直接給出合成座標。這起作用是偶然的和無證的。 – bigreddot

+0

所以最好的做法是不使用因子範圍,並將y軸標籤與FuncTickFormatter進行映射?那麼數據並不是真正的分類,而只是y軸的重新標記。否則將需要抵消實際值,如海報試圖 – Anthonydouc

+0

沒有理由不使用真正的分類,即「FactorRange」。分類可以在'0.12.6'和之前用高頻''foo:0.2''語法進行偏移。在'0.12.7'中會支持真正的嵌套分類,因此只需要分組就可以不需要偏移,即使需要偏移,也可以使用'[「foo」,0.2]'這是一個更健壯的語法。 – bigreddot