Как изобразить персонажей в боке - PullRequest
0 голосов
/ 12 июня 2019

У меня есть пандас DataFrame, в котором все значения являются английскими алфавитами или пустой строкой "".Моя цель состоит в том, чтобы а) построить эти алфавиты, взяв индекс столбца за ось X и индекс строки за ось Y (график разброса) и б), чтобы иметь возможность контролировать расстояние в направлении оси X, чтобы они не располагались на большом расстоянии друг от друга.

Мне удалось построить глифы (например, кружок) по нужным координатам, но не по алфавиту (как они появляются в кадре данных).А также эти круги были широко разнесены, поскольку ось X имеет 0,1,2,3 ....Ось X также может быть сделана категориальной вместо целых, если это обеспечивает простое / лучшее решение.

import pandas as pd
from bokeh.plotting import figure
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource,Range1d #FactorRange

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"]}
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))
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)
show(fig)

Как упоминалось ранее, приведенный выше код изображает один глиф (в данном случае кружок) - это не то, чего я хочу, и, кроме того, я абсолютно не знаю, как добиться контроля над масштабированием.

1 Ответ

0 голосов
/ 22 июня 2019

Вам необходимо создать список из данных, которые вы хотите построить, той же длины, что и другие в 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)
...