☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

How to draw twin axis, where one is categorical and the other is numerical

Community Support
Royalblue
Royalblue

I’d like to draw a plot with twin axis, where one is categorical and the other is numerical.

I tried the following code but it throws an error.

x = pd.Series([‘2017/1/1’, ‘2017/1/2’, ‘2017/1/3’, ‘2017/1/4’]).map(lambda x: parse(x))
y = [“a”, “b”, “c”, “a”]
y2=[1,10,4,8]

p = figure(x_axis_type=‘datetime’, y_range=FactorRange(factors=list(set(y))), plot_width=400, plot_height=200)

p.circle(x, y, size=10, color=“blue”)

#p.vbar(x=x, bottom=0, top=y, width=0.1, color=“blue”)

p.extra_y_ranges={‘count’: Range1d(start=0, end=11)}
p.circle(x, y, size=10, color=“red”, y_range_name=‘count’)
p.add_layout(LinearAxis(y_range_name=“count”), ‘right’)

show(p)

···

Here is error message:

E-1009 (INCOMPATIBLE_SCALE_AND_RANGE): A Scale is incompatible with one or more ranges on the same plot dimension: incompatibility on y-dimension: Range1d(id=‘79319bcd-f740-4aa3-8358-b153158d7436’, …), CategoricalScale(id=‘83e32163-4bf9-494c-973a-a63a00b57549’, …) [Figure(id=‘e542157c-8d8e-4b65-b0df-ab1e4c2a69f8’, …)]
W-1005 (SNAPPED_TOOLBAR_ANNOTATIONS): Snapped toolbars and annotations on the same side MAY overlap visually: Figure(id=‘e542157c-8d8e-4b65-b0df-ab1e4c2a69f8’, …)

Javascript error adding output!
Error: Range Range1d is incompatible is Scale CategoricalScale
See your browser Javascript console for more details.


Could someone share a solution?

⌁   Link to post
Bryan
Bryan

This is certainly not currently going to work. Making it work would require some thought and discussion, as it's not clear to me what "correct" behavior would be in many cases, when imagining combining a categorical and non-categorical axis. If you'd like to propose it as a new feature, a GitHub issue is the place to start:

  Issues · bokeh/bokeh · GitHub

But I will be honest and say that there are many current high priorities, and its not likely any core dev would be able to look at it any time soon. A better option in the immediate term is a non-categorical axis and custom tick formatting to display whatever text you want, a tick formatter:

  Appearance — Bokeh 3.3.2 Documentation

or label overrides:

  http://bokeh.pydata.org/en/latest/docs/reference/models/axes.html#bokeh.models.axes.Axis.major_label_overrides

Thanks,

Bryan

···

On Aug 16, 2017, at 07:15, Royalblue <royalblue.cho@gmail.com> wrote:

I'd like to draw a plot with twin axis, where one is categorical and the other is numerical.

I tried the following code but it throws an error.

x = pd.Series(['2017/1/1', '2017/1/2', '2017/1/3', '2017/1/4']).map(lambda x: parse(x))
y = ["a", "b", "c", "a"]
y2=[1,10,4,8]

p = figure(x_axis_type='datetime', y_range=FactorRange(factors=list(set(y))), plot_width=400, plot_height=200)

p.circle(x, y, size=10, color="blue")

#p.vbar(x=x, bottom=0, top=y, width=0.1, color="blue")

p.extra_y_ranges={'count': Range1d(start=0, end=11)}
p.circle(x, y, size=10, color="red", y_range_name='count')
p.add_layout(LinearAxis(y_range_name="count"), 'right')

show(p)

----------------------------------------------------------------------------------------------------------------------------------------------------------
Here is error message:

E-1009 (INCOMPATIBLE_SCALE_AND_RANGE): A Scale is incompatible with one or more ranges on the same plot dimension: incompatibility on y-dimension: Range1d(id='79319bcd-f740-4aa3-8358-b153158d7436', ...), CategoricalScale(id='83e32163-4bf9-494c-973a-a63a00b57549', ...) [Figure(id='e542157c-8d8e-4b65-b0df-ab1e4c2a69f8', ...)]
W-1005 (SNAPPED_TOOLBAR_ANNOTATIONS): Snapped toolbars and annotations on the same side MAY overlap visually: Figure(id='e542157c-8d8e-4b65-b0df-ab1e4c2a69f8', ...)

Javascript error adding output!
Error: Range Range1d is incompatible is Scale CategoricalScale
See your browser Javascript console for more details.

----------------------------------------------------------------------------------------------------------------------------------------------------------
Could someone share a solution?

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+unsubscribe@continuum.io.
To post to this group, send email to bokeh@continuum.io.
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/7ca35b5e-4c6a-4b5f-ab32-f28ea5e5e016%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

⌁   Link to post
Royalblue
Royalblue

Thank you Bryan for the alternative methods. It works perfectly as I intend.

I did something like this according to the userguide:

feature_list = a_un_history[‘feature’].unique()

num_to_feature = dict(zip(range(len(feature_list)), feature_list))

feature_to_num = {v:k for k,v in num_to_feature.items()}

x = a_un_history[‘generation_timestamp’]

p = figure(plot_width=800, plot_height=400,

x_axis_type=“datetime”,

tools=[‘xzoom_in’, ‘xzoom_out’, ‘xpan’, ‘reset’])

p.y_range = Range1d(-0.1,len(feature_list)-0.8)

p.extra_y_ranges = {“RSSI”: Range1d(-100, 10)}

p.add_layout(LinearAxis(y_range_name=“RSSI”), ‘left’)

p.circle(x=x, y=a_un_history[‘feature’].map(feature_to_num) ,size=1, line_color=“blue”, line_width=3)

p.yaxis[0].major_label_overrides = num_to_feature

p.circle(x, a_un_history[‘RSSI’], color=‘red’, y_range_name=“RSSI”)

p.add_tools(BoxZoomTool(dimensions=“width”))

show(p)

2017년 8월 16일 수요일 오후 11시 26분 26초 UTC+9, Bryan Van de ven 님의 말:

···

This is certainly not currently going to work. Making it work would require some thought and discussion, as it’s not clear to me what “correct” behavior would be in many cases, when imagining combining a categorical and non-categorical axis. If you’d like to propose it as a new feature, a GitHub issue is the place to start:

    [https://github.com/bokeh/bokeh/issues](https://github.com/bokeh/bokeh/issues)

But I will be honest and say that there are many current high priorities, and its not likely any core dev would be able to look at it any time soon. A better option in the immediate term is a non-categorical axis and custom tick formatting to display whatever text you want, a tick formatter:

    [http://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#functickformatter](http://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#functickformatter)

or label overrides:

    [http://bokeh.pydata.org/en/latest/docs/reference/models/axes.html#bokeh.models.axes.Axis.major_label_overrides](http://bokeh.pydata.org/en/latest/docs/reference/models/axes.html#bokeh.models.axes.Axis.major_label_overrides)

Thanks,

Bryan

On Aug 16, 2017, at 07:15, Royalblue royalb...@gmail.com wrote:

I’d like to draw a plot with twin axis, where one is categorical and the other is numerical.

I tried the following code but it throws an error.

x = pd.Series([‘2017/1/1’, ‘2017/1/2’, ‘2017/1/3’, ‘2017/1/4’]).map(lambda x: parse(x))

y = [“a”, “b”, “c”, “a”]

y2=[1,10,4,8]

p = figure(x_axis_type=‘datetime’, y_range=FactorRange(factors=list(set(y))), plot_width=400, plot_height=200)

p.circle(x, y, size=10, color=“blue”)

#p.vbar(x=x, bottom=0, top=y, width=0.1, color=“blue”)

p.extra_y_ranges={‘count’: Range1d(start=0, end=11)}

p.circle(x, y, size=10, color=“red”, y_range_name=‘count’)

p.add_layout(LinearAxis(y_range_name=“count”), ‘right’)

show(p)


Here is error message:

E-1009 (INCOMPATIBLE_SCALE_AND_RANGE): A Scale is incompatible with one or more ranges on the same plot dimension: incompatibility on y-dimension: Range1d(id=‘79319bcd-f740-4aa3-8358-b153158d7436’, …), CategoricalScale(id=‘83e32163-4bf9-494c-973a-a63a00b57549’, …) [Figure(id=‘e542157c-8d8e-4b65-b0df-ab1e4c2a69f8’, …)]

W-1005 (SNAPPED_TOOLBAR_ANNOTATIONS): Snapped toolbars and annotations on the same side MAY overlap visually: Figure(id=‘e542157c-8d8e-4b65-b0df-ab1e4c2a69f8’, …)

Javascript error adding output!

Error: Range Range1d is incompatible is Scale CategoricalScale

See your browser Javascript console for more details.


Could someone share a solution?

–
You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+un...@continuum.io.

To post to this group, send email to bo...@continuum.io.

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/7ca35b5e-4c6a-4b5f-ab32-f28ea5e5e016%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

⌁   Link to post

End of archived discussion · Replies are disabled