-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
How to plot with different colors when using Dot Charts and Bar Charts? #1967
Comments
It might be easier to help with some specific code that's not working. I believe there are examples in the gallery and in the examples folder that cover this need: http://bokeh.pydata.org/en/latest/docs/gallery/iris.html Also see my comment here, about how to customize those colors. |
OK the above link for your comment worked I am able to plot different Dot/Bar charts in different colors. |
Have you looked at this: http://bokeh.pydata.org/en/latest/docs/gallery/color_scatter.html |
Sorry @pofican I'd love to be more helpful but I don't understand your needs. I'm not sure if you need a new a mixed Scatter and Bar chart or just a different use the Dot and Bar. |
@birdsarah @fpliger scatter example is not helpful for my case, below I put a sample code which might help you understand what I am trying to do and this code is not working because the expected data type for a Dot object is a list not an element of a list. Briefly, lets say I have a data list and I want to assign a different color for each element of this list and plot it using Dot/Bar, like in the example below I would like to see x(it's value in this case is 1) green, y (value 2) blue, and z (value 3) yellow. I didn't see any related examples in the documentation, am I missing anything here? Is this doable with Bokeh? First scenario (The example is trying different colors of blue. I don't even know how I can assign green, blue, yellow to each data point): x = [1, 2, 3]
y = ['x', 'y', 'z']
output_file("dots.html")
palette_key = 3
for i,j in zip(x,y):
palette = brewer["Blues"][palette_key]
dots = Dot(i, cat = j, title="Data", ylabel='FP Rate', xlabel='Vendors',filename="dots.html", legend=False, palette = palette)
palette_key = palette_key + 1
show(VBox(HBox(dots)))
>>> ValueError: expected an element of either Bool or List(Any), got 'x' Second scenario, I tried cat= None and getting another error related to the first element of Dot function, because it expects a list not an element of the list. x = [1, 2, 3]
y = ['x', 'y', 'z']
output_file("dots.html")
palette_key = 3
for i,j in zip(x,y):
palette = brewer["Blues"][palette_key]
dots = Dot(i, cat = None, title="Data", ylabel='FP Rate', xlabel='Vendors',filename="dots.html", legend=False, palette = palette)
palette_key = palette_key + 1
show(VBox(HBox(dots)))
>>>> Input type not supported! 1 |
@fpliger @birdsarah @damianavila @bryevdv any ideas? Is my question clear? Is this doable with bokeh? |
@pofican palettes operate on grouped data in a single plot. I still can't tell if you want all the data on one plot or not. But in any case, you are not passing in groups. Try this to get dots with different colors on one plot:
If you want multiple charts with a different color for each chart, I am actually not sure there is a way to control the "dot" color directly (if not that is an oversight). @fpliger can you comment, is there a way to control the dot color? I tried passing a |
@bryevdv the first example that you put above what I was asking for but when I add categories all values are plotted under just one category. I couldn't find a way to get around this... Any ideas? from bokeh.charts import *
xyvalues=dict(x=[1], y=[2], z=[3])
cat = xyvalues.keys()
dots = Dot(
xyvalues, cat = cat, title="Data", ylabel='FP Rate',
xlabel='Vendors',filename="dots.html", legend=False,
palette=["red", "green", "blue"])
show(dots) |
@pofican In your last example you are listing 3 categories but on data series you are only providing one value (so only for the first category). The categories refers to the categories to map to the values listed on each data series element and not to the data series themselves. Is it should have the same length as the values lists of your data ( |
@fpliger I didn't clearly get what you are saying above. What is the proper way of calling Dots function with a list of values where each value maps a different category? If you can give a simple example that would be great. Because I don't think what I am asking is doable using Bokeh, I have tried couple of ways and none of them worked. |
@pofican sorry for not being clear... I'll try to comment your example above (with some modifications to make it easier) to explain: from bokeh.charts import *
# here you create the data to be consumed by the Dot chart. It is a dict where:
# * the keys define the names of the series to display . Basically defines how many
# * the values are iterables of scalar where each scalar value defines the value of the serie to show
# on each serie. Basically defines the height of the dot on the specific category.
xyvalues=dict(A=[1, 2], B=[2, 2], C=[3, 7]) # on your example was 'xyvalues=dict(x=[1], y=[2], z=[3])'
# the categories related to the values defined in xyvalues. This should have the same length
# of the iterables defined as values in xyvalues
cat = ["BOB", "BEN"] #on your example was 'cat = xyvalues.keys()'
dots = Dot(
xyvalues, cat = cat, title="Data", ylabel='FP Rate',
xlabel='Vendors',filename="dots.html", legend=False,
palette=["red", "green", "blue"])
show(dots) The previous code creates: Let me know if it's clears your doubts. Thanks! |
I modifed the circle example and able to plot the below. But I would like to be plot a similar plot using Dot/Bar, is this possible? from bokeh.plotting import *
factors = ["a", "b", "c"]
x0 = [0, 0, 0]
x = [50, 40, 65]
output_file("categorical.html", title="categorical.py example")
p1 = figure(title="Dot Plot", tools="resize,save", y_range=factors, x_range=[0,100])
p1.segment(x0, factors, x, factors, line_width=2, line_color=["orange","green","red"])
p1.circle(x, factors, size=15, fill_color=["orange","green","red"], line_color=["orange","green","red"], line_width=3, )
show(p1) |
@pofican you are considering categories conceptually in a different way they are in charts. AFAIK charts (both Bar and Dot) cannot produce what you'd like. But the good new is that it's fairly easy to create a new chart builders that does what you'd like. Here's a quick implementation that should do what you need: import numpy as np
from bokeh.charts import *
from bokeh.plotting import show, output_file
from bokeh.charts._builder import create_and_build
from bokeh.charts.builder.dot_builder import DotBuilder, cycle_colors, FactorRange, \
Range1d, make_scatter, Segment, GlyphRenderer
class FlatDotBuilder(DotBuilder):
def _process_data(self):
if not self.cat:
self.cat = [str(x) for x in self._values.index]
values = self._values.values()
self._data = dict(
cat=self.cat, zero=np.zeros(len(self.cat)),
values=values[0],
colors=cycle_colors(values[0], self.palette)
)
self._groups=self._values.keys()
def _set_sources(self):
self._source = ColumnDataSource(self._data)
self.x_range = FactorRange(factors=self._source.data["cat"])
end = 1.1 * max(self._data['values'])
self.y_range = Range1d(start=0, end=end)
def _yield_renderers(self):
if self.stem:
glyph = Segment(
x0='cat', y0='zero', x1='cat', y1='values',
line_color="colors", line_width=2
)
yield GlyphRenderer(data_source=self._source, glyph=glyph)
renderer = make_scatter(
self._source, 'cat', 'values', 'circle',
'colors', size=15, fill_alpha=1.
)
self._legends.append((self._groups[0], [renderer]))
yield renderer
def FlatDot(values, cat=None, stem=True, xscale="categorical", yscale="linear",
xgrid=False, ygrid=True, **kws):
return create_and_build(
FlatDotBuilder, values, cat=cat, stem=stem, xscale=xscale, yscale=yscale,
xgrid=xgrid, ygrid=ygrid, **kws
)
cat = ["BOB", "BEN", "JOB"]
output_file('dots.html')
# this works with just [10, 20, 30] as well
dots = FlatDot(
{"FP RATE": [10, 20, 30]},
cat=cat, title="Data", ylabel='FP Rate',
xlabel='Vendors',
palette=["red", "yellow", "blue"]
)
show(dots) please note that legend "is wrong" but I left as is because I'm not really sure how you'd like it to behave. Here's how the former code looks like: |
@fpliger Thanks for the response, I am closing this discussion at this point then. |
I would like to have a dot/bar plot where each dot/bar that belongs to a different category has a different color, is it possible to do this with Bokeh?
Also when I try to plot a dot chart lets say for 3 diffenrent group of categories all the dot plots appears to be red. Is there a way I could at least change the color of dot plots for different data sets?
Thanks in advance!
The text was updated successfully, but these errors were encountered: