elaspog
elaspog

Reputation: 1709

Using DataSource in bokeh library for color, alpha and other properties

So far in python's bokeh library I've used a patch method to draw some objects, but the current solution runs in a for loop which is not optimal for this library:

for data_point in data_points:
    tf_sec    = pd.Timedelta(data_point['tf']) / 2.0
    dt        = tf_sec + datetime.strptime(data_point['dt'], '%Y-%m-%d %H:%M:%S')
    p         = float(data_point['p'])
    p_diff    = p * 0.005
    p_offset  = (p + p_diff * data_point['va'])

    obj = plot.patch(
        x          = [dt, dt - tf_sec, dt + tf_sec],
        y          = [p, p_offset, p_offset],
        color      = COLOR_MAP.get(data_point.get('type'), DEFAULT_COLOR),
        fill_alpha = data_point.get('color_ratio', 1.0),
        line_alpha = 1.0,
    )

Now I want to optimize this solution and draw the objects with a DataSource using pandas.

The X and Y columns are working fine, they accept the value, but if I try to define the other columns (e.g.: color, fill_alpha, line_alpha etc.) they don't accept the value from the datasource, but they raise an error:

ValueError: failed to validate Patch(id='p1179', ...).fill_color: expected either None or a value of type Color, got 'color'

If I understand correctly, these properties are not configured to accept this referenced column of values.

Question

Requirements

My current version is:

data_points_df['tf_sec']     = data_points_df.apply(lambda row: pd.Timedelta(row['tf']) / 2.0, axis=1)
data_points_df['dt']         = data_points_df.apply(lambda row: row['dt'] + row['tf_sec'], axis=1)
data_points_df['p_offset']   = data_points_df.apply(lambda row: row['p'] + 0.005 * row['p'] * row['va'], axis=1)
data_points_df['x']          = data_points_df.apply(lambda row: [row['dt'], row['dt'] - row['tf_sec'], row['dt'] + row['tf_sec']], axis=1)
data_points_df['y']          = data_points_df.apply(lambda row: [row['p'], row['p_offset'], row['p_offset']], axis=1)
data_points_df['color']      = data_points_df.apply(lambda row: COLOR_MAP.get(row['type']) if row['type'] in COLOR_MAP else DEFAULT_COLOR, axis=1)
data_points_df['fill_alpha'] = data_points_df.apply(lambda row: row['color_ratio'] if 'color_ratio' in data_points_df.columns else 1.0, axis=1)
data_points_df['line_alpha'] = 1.0

obj = plot.patch(
    source     = ColumnDataSource(data_points_df),
    x          = 'x',
    y          = 'y',
    color      = ???,
    fill_alpha = ???,
    line_alpha = ???,
)

Upvotes: 0

Views: 22

Answers (0)

Related Questions