Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List of color tuples broken? #2622

Closed
jmhessel opened this issue Jul 27, 2015 · 17 comments · Fixed by #3904
Closed

List of color tuples broken? #2622

jmhessel opened this issue Jul 27, 2015 · 17 comments · Fixed by #3904

Comments

@jmhessel
Copy link

I think that bokeh doesn't properly support lists of colors at the moment.

from bokeh.plotting import figure, show, output_file

output_file("broken.html")
xs = [1,2,3]
ys = [1,2,3]
col = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]

p = figure(title = "Broken")
p.circle(xs, ys, radius=.25, color=col)
show(p)

When I run this code, I get 3 circles with no color. The documentation seems to suggest that colors can be passed in this way.

bokeh.version is 0.9.2

@jmhessel jmhessel changed the title List of colors broken List of colors broken? Jul 27, 2015
@bryevdv
Copy link
Member

bryevdv commented Jul 27, 2015

Just to be clear, the problem is only with lists of color tuples. There are many examples with lists of color strings, e.g. "blue" or "#ff0000".

@jmhessel jmhessel changed the title List of colors broken? List of color tuples broken? Jul 27, 2015
@damianavila damianavila added this to the short-term milestone Jul 27, 2015
@canavandl
Copy link
Contributor

When you set the color property as a RGB-style tuple, Bokeh (correctly) sets the fill/line_color attrs of the dataspec map as ColorSpec instances that get serialized to CSS-style RGB strings in JSON, like:

...
 {'attributes': {'doc': None,
   'fill_alpha': {'value': 1.0},
   'fill_color': {'value': 'rgb(5, 3, 77)'}, /// note CSS-style string
   'id': '2e4667b9-f6ad-4c7d-baa6-f20e054bc92f',
   'line_alpha': {'value': 1.0},
   'line_color': {'value': 'rgb(5, 3, 77)'}, /// note CSS-style string
   'radius': {'units': 'data', 'value': 0.25},
   'tags': [],
   'x': {'field': 'x'},
   'y': {'field': 'y'}},
  'id': '2e4667b9-f6ad-4c7d-baa6-f20e054bc92f',
  'type': 'Circle'},
...

However, when setting a glyph property as a sequence (i.e. x, y, or color), the RGB-style list gets set as a named column in the plot's ColumnDataSource and the fill/line_color attrs get set as the keys. This is a problem because the 3-element lists don't correspond to CSS colors when the plots are rendered on the client.

...
{'attributes': {'callback': None,
   'column_names': ['y', 'x', 'line_color', 'fill_color'],
   'data': {'fill_color': [[255, 0, 0], [0, 255, 0], [0, 0, 255]], /// note list of 3-element lists and not color strings
    'line_color': [[255, 0, 0], [0, 255, 0], [0, 0, 255]], /// note list of 3-element lists and not color strings
    'x': [1, 2, 3],
    'y': [1, 2, 3]},
   'doc': None,
   'id': 'bbe768fc-f22d-4be0-b2ad-57f8e69d9040',
   'selected': {'0d': {'flag': False, 'indices': []},
    '1d': {'indices': []},
    '2d': {'indices': []}},
   'tags': []},
  'id': 'bbe768fc-f22d-4be0-b2ad-57f8e69d9040',
  'type': 'ColumnDataSource'},
 {'attributes': {'doc': None,
   'fill_alpha': {'value': 1.0},
   'fill_color': {'field': 'fill_color'}, /// note 'field' key to ColumnDataSource
   'id': '4a5ab396-9ae5-475c-8640-dc820fdfac97',
   'line_alpha': {'value': 1.0},
   'line_color': {'field': 'line_color'}, /// note 'field' key to ColumnDataSource
   'radius': {'units': 'data', 'value': 0.25},
   'tags': [],
   'x': {'field': 'x'},
   'y': {'field': 'y'}},
  'id': '4a5ab396-9ae5-475c-8640-dc820fdfac97',
  'type': 'Circle'},
... 

Work arounds include passing lists of CSS-style RGB strings like:

col = ["rgb(255, 0, 0)", "rgb(0, 255, 0)", "rgb(0, 0, 255)"]

or RGB class instances (because their repr is the CSS-style string)

from bokeh.colors import RGB
col = [RGB(255, 0, 0), RGB(0, 255, 0), RGB(0, 0, 255)]

Definitely, making the docs more explicit about styling colors is needed.

Code changes:
It'd be possible to check the color property for a list of RGB tuples and set the ColumnDataSource fill/line_color columns as lists of CSS-style RGB strings, but it seems (to me) inadvisible to mutate the ColumnDataSource values from how they were set.

Alternatively, it'd be possible to check/update the fill/line_color props on the BokehJS side, but it seems unwise for the same reasons.

@canavandl
Copy link
Contributor

ref issue #2615

@jbednar
Copy link
Contributor

jbednar commented Oct 11, 2016

This issue is mentioned in the docs:

image

but that's confusing, because the issue was closed in February yet the docs are describing problems that are presumably unresolved. Also, the docs in this screenshot say that RGBA hex colors are allowed, i.e. hex strings with 8 color characters, yet there seems to be an explicit limitation to 6 color characters in hex strings, based on this message when setting a color property:

ValueError: expected an element of either Enum('aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'), Regex('^#[0-9a-fA-F]{6}$'), Tuple(Byte(Int, 0, 255), Byte(Int, 0, 255), Byte(Int, 0, 255)) or Tuple(Byte(Int, 0, 255), Byte(Int, 0, 255), Byte(Int, 0, 255), Percent), got '#33333300'

(I.e., there is a regexp specifically looking for a {6}-hex-character string, but nothing allowing an 8-hex-character string.)

@ibmua
Copy link

ibmua commented May 7, 2017

I'm trying to set the color for
bokeh.charts.Area
For me only named colors and strings like "#aabbcc" work. Neither colors.RGB/HSL, nor "rgb(255, 0, 0)", etc work. colors.RGB/HSL colors get completely ignored, while stuff like "rgb(255, 0, 0)" triggers an error.

Hacked around this crap by using https://pypi.python.org/pypi/colour/0.0.5 like

Color	(
	hsl	=	(	.2	, .2	, .7	)
	).hex_l

HSL is really one of the most essential parts of graphs, IMHO.

The question is why even make the ton of checks if you can't make them right? Should have simply let users set color as a string that would be passed directly to CSS.

@bryevdv
Copy link
Member

bryevdv commented May 8, 2017

The question is why even make the ton of checks if you can't make them right? Should have simply let users set color as a string that would be passed directly to CSS.

For one, Bokeh draws on the HTML canvas, so CSS is irrelevant. Supporting these colors means converting them, which means detecting them, which means validation. It's obvious that a regression has occurred, and certainly we'd like to fix any regressions. But perhaps you can consider that you might not have all the relevant information before making assumptions in a disparaging way?

This issue is old and has a number of cross discussions related to old versions of the codebase, I would appreciate if you would open a new issue to handle this.

@ibmua
Copy link

ibmua commented May 8, 2017

Yeah, my mistake, sorry, I first thought you were using SVG. CSS colors do work with Canvas fillStyle https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle , but yes, I don't have enough info on the internal workings, some other part might not support them. It might be that you're writing directly into a typed array, for example.

It might make sense to include Colour module to work on converting colors under the rug.

@bryevdv
Copy link
Member

bryevdv commented May 8, 2017

@ibmua we actually have code to handle the conversions:

https://github.com/bokeh/bokeh/blob/master/bokeh/colors.py

The issue is in the machinery that has to decide, when a user says color=THING, is "THING"

  • a string name of a data source column??
  • string name of a color? (in any of the many formats of colors)
  • a sequence representing a single color?
  • a sequence representing a sequence of colors (which might be strings, or subsequences...)

But as I mentioned new issue would be the best place to figure this out.

@bryevdv
Copy link
Member

bryevdv commented May 8, 2017

@ibmua I made a new issue you can follow #6258

@bryevdv
Copy link
Member

bryevdv commented May 8, 2017

@ibmua FYI this RGB tuple is currently working for me:

from bokeh.events import ButtonClick
from bokeh.io import output_file, show
from bokeh.plotting import figure

p = figure()
p.line([1,2,3,4], [2,5,8,3], line_width=2, color=(255, 150, 200))

output_file("foo.html")

show(p)

So if RGB tuples are not working for you with a bokeh.chart it is possible that the problem is specific to the charts API. But that is moving to its own repo and project, any charts related issues should now go in https://github.com/bokeh/bkcharts

@ibmua
Copy link

ibmua commented May 8, 2017

Thanks, @bryevdv !

I didn't try tuples like in your above example - didn't know about that functionality and wanted hsl anyway, because I wanted to paint related stuff with a same hue. Only tried colors.RGB, colors.HSL and CSS-style. Out of CSS stuff, also 3-hex-digit-codes like #aaa didn't work, which is why I used Colour module with .hex_l so that it would convert to stuff like #aaaaaa.

@bryevdv
Copy link
Member

bryevdv commented May 8, 2017

FYI I made a note in the new issue to make sure hsl(.....) etc is correctly handled.

@sergeyfridrikh
Copy link

RGB 3 element tuples or colors.RGB objects still do not work for marker colors of scatter plots. I guess the fix was not put in all graphic objects using colors.

@bryevdv
Copy link
Member

bryevdv commented Mar 8, 2018

@sergeyfridrikh please prove test code / reproducing example in a new issue.

@sergeyfridrikh
Copy link

Found a bug. colors.RGB objects works for scatter plots as well. My aplologies.

@kkumawat25
Copy link

How to use a palette in this case, is there any way to convert a list of tuples to RGB format?

@bryevdv
Copy link
Member

bryevdv commented Oct 11, 2019

@kkumawat25 GitHub is not the appropriate venue for support/usage questions. Please use the project Discourse:

https://discourse.bokeh.org/

@bokeh bokeh locked and limited conversation to collaborators Oct 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants