Вам необходимо создать список из данных, которые вы хотите построить, той же длины, что и другие в columndatasource, а затем добавить его в свой источник. Вы можете отключить свои круги, если вы хотите использовать только символы, иначе оба будут нанесены на график, вы также должны рассмотреть возможность использования пылесоса, который является очень хорошим способом добавить взаимодействие в сюжет.
Я использовал LabelSet для отображения координат ваших данных, вы также можете поиграть со смещениями, чтобы отрегулировать интервал, как вы упомянули.
import pandas as pd
from bokeh.plotting import figure
from bokeh.io import output_file, show, output_notebook
from bokeh.models import ColumnDataSource,Range1d, LabelSet #FactorRange
import itertools
output_notebook()
output_file("plot_text.html",title="plot_text")
# creating the DataFrame
d = {0:["A","A","A","D","D","C","E"],
1:["B","","B","C","D","E","E"],
2:["","","F","F","G","","H"],
3:["","","","","","H","H"]}
#convert dict to a single list to match the length in your
#source(ColumnDataSource)
d1 = list(d.values())
d_letters = list(itertools.chain(*d1))
#I tried to remove your nan values, but it didnt work, I did it manually but
#here is the code to do so
d2 = [x for x in d_letters if d_letters != ''] # [x for x in d_letters if
#d_letters != 'nan']
d_ = ['A', 'A', 'A', 'D', 'D', 'C', 'E', 'B', 'B', 'C','D', 'E', 'E', 'F',
'F', 'G', 'H', 'H', 'H']
#len(d_) 19 as x and y
df = pd.DataFrame(d,index=range(800,100,-100))
list1_x = []
list1_y = []
for i in range(len(df.columns)):
for j in range(len(df.index)):
if df.iloc[j,i]=="": # excluding the "" appearance
continue
else:
list1_x.append(df.columns[i])
list1_y.append(df.index[j])
source = ColumnDataSource(data=dict(x = list1_x,y = list1_y, x1=d_))
fig = figure(plot_height=500, plot_width=1100,
tools="pan,xwheel_zoom,reset,save,crosshair,box_zoom",
active_drag='pan',
active_scroll='xwheel_zoom',
x_range=Range1d(-5, 100, bounds="auto"),
y_range=Range1d(-100, 1200, bounds="auto")
)
fig.circle(x= 'x',y='y',color = "blue",size =10,source = source)
#create labels
labels = LabelSet(x='x', y='y', text='x1', level='glyph',
x_offset=5, y_offset=5, source=source, render_mode='canvas')
fig.add_layout(labels)
show(fig)