Fred
Fred

Reputation: 49

Data and X axis labels not align

Trying to plot X axis (Event) values on their respective x Axis. Y axis is relative to Time (of the day) when and how long the event lasted. The first label and data plotted are correct. However, the second set of data appears to skip over the major x axis tick and is placed afterwards but before the next major x axis tick. This is repeated for each additional x Axis value plotted. The data does not show a problem with which X axis it should appear on.

Defined the data (source) and can plot the issue with about 50 lines of code.

from bokeh.io import output_file
from bokeh.models import ColumnDataSource, LabelSet
from bokeh.plotting import figure, show
from bokeh.models.formatters import NumeralTickFormatter
import pandas as pd
import math

output_file("events.html", mode="inline")

x1 = []
y1 = []
x2 = []
y2 = []
colorList = []
shortNames = []

nameAndId = ["Event1", 0]
x1.append(nameAndId)
y1.append(33470)
x2.append(nameAndId)
y2.append(33492)
colorList.append("red")
shortNames.append("Evt1")

nameAndId = ["Event2", 1]
x1.append(nameAndId)
y1.append(34116)
x2.append(nameAndId)
y2.append(34151)
colorList.append("green")
shortNames.append("Evt2")

xAxisLabels = ["Event1", "Event2"]

data = {"x1": x1, "y1": y1, "x2": x2, "y2": y2, "color": colorList,\
        "shortName": shortNames}

eventDF = pd.DataFrame(data=data,
                       columns=("x1", "y1", "x2", "y2", "color",\
                                "shortName"))

source = ColumnDataSource(eventDF)

yRange = [34151, 33470]
p = figure(plot_width=700, plot_height=750, x_range=xAxisLabels,\
           y_range=yRange, output_backend="webgl")

p.xaxis.major_label_orientation = math.pi / -2
p.segment(x0="x1",y0="y1",x1="x2",y1="y2", source=source, color="color"\
          line_width=12)
p.yaxis[0].formatter = NumeralTickFormatter(format="00:00:00")
p.xaxis.axis_label = "Events"

labels = LabelSet(x="x2",y="y2", text="shortName", text_font_size="8pt"\
                  text_color="black", level="glyph", x_offset=-6,\
                  y_offset=-5, render_mode="canvas", angle=270,\
                  angle_units="deg", source=source)
p.add_layout(labels)
show(p)

I'm thinking this is something simple I've over-looked like a xAxis formatter. I've tried to define one but none seem to work for my use case. The data doesn't seem to be associated to the xAxisLabel. I Expect Event 1 to show on the first X axis tick with Event 2 on the second X axis tick. Event 1 is correct but for each event afterwards, every major X axis tick is skipped with the data residing between tick marks.

Upvotes: 1

Views: 718

Answers (1)

bigreddot
bigreddot

Reputation: 34568

The issue in your code is that the actual value for the x-coordinate you are supplying is:

nameAndId = ["Event2", 1]

This kind of list with a category name and a number in a list is understood by Bokeh as a categorical offset. You are explicitly telling Bokeh to position the glyph a distance of 1 (in "synthetic" coordinates) away from the location of "Event2". The reason things "work" for the Event1 case is that the offset in that case is 0:

nameAndId = ["Event1", 0]

I'm not sure what you are trying to accomplish by passing these lists with the second numerical value, so I can't really offer any additional suggestion except to say that it should probably not be passed on to Bokeh.

Upvotes: 1

Related Questions