3

I am trying to plot line chart for the length of the list "w" in below code. when i use spectral11 from bokeh all i get are only 11 lines on the chart where as the list contain 24 parameters. are there any other palettes which allows me to plot all the lines from the list "w"

#Import the library
import pandas 
import bokeh
import MySQLdb
from bokeh.plotting import figure, output_file, show
from bokeh.palettes import Spectral11


w=['F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12','G1','G2','G3','G4','G5','G6','G7','G8','G9','G10','G11','G12']

p = figure(plot_width=800, plot_height=500, x_axis_type="datetime")
p.title.text = 'Click on legend entries to hide the corresponding lines'
# Open database connection
db = MySQLdb.connect("localhost","user","password","db" )

In the below for loop only 11 dataframes are formed which eventually plotting those 11 lines.

for name, color in zip(w, Spectral11):
   stmnt='select date_time,col1,w,test_value from db where w="%s"'%(name)
   df=pandas.read_sql(stmnt,con=db)

p.line(df['date_time'], df['test_value'], line_width=2, color=color, alpha=0.8, legend=name)

p.legend.location = "top_left"
p.legend.click_policy="hide"

output_file("interactive_legend.html", title="interactive_legend.py example")

show(p)

below is the resultant plot of the code the resultant image of the above code

2
  • Please post a minimal reproducible example, using dummy data if necessary. We're not going to be much help if we don't know what is in wells or Spectra11 (although the fact that it is named "11" and you have 11 plots seems to not be a coincidence...). Are you sure you're supposed to get 24 plots? Commented Apr 10, 2017 at 15:44
  • I Know with Spectral11 only 11 can be plotted, wanted to know about other palettes which gives me the option of more than 11 Commented Apr 10, 2017 at 19:10

2 Answers 2

3

The issue is that zip truncates at the end of the shorter list.

In [1]: from bokeh.palettes import Spectral11

In [2]: w=['F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12','G1','G2','G3','G4','G5','G6','G7','G8'
    ...: ,'G9','G10','G11','G12']

In [3]: for name, color in zip(w, Spectral11):
    ...:     print(name, color)
    ...:
F1 #5e4fa2
F2 #3288bd
F3 #66c2a5
F4 #abdda4
F5 #e6f598
F6 #ffffbf
F7 #fee08b
F8 #fdae61
F9 #f46d43
F10 #d53e4f
F11 #9e0142

Choosing a palette longer than your w list would resolve this (as @PabloReyes mentioned). You could also use itertools.cycle.

In [4]: import itertools

In [5]: for name, color in zip(w, itertools.cycle(Spectral11)):
    ...:     print(name, color)
    ...:
F1 #5e4fa2
F2 #3288bd
F3 #66c2a5
F4 #abdda4
F5 #e6f598
F6 #ffffbf
F7 #fee08b
F8 #fdae61
F9 #f46d43
F10 #d53e4f
F11 #9e0142
F12 #5e4fa2
G1 #3288bd
G2 #66c2a5
G3 #abdda4
G4 #e6f598
G5 #ffffbf
G6 #fee08b
G7 #fdae61
G8 #f46d43
G9 #d53e4f
G10 #9e0142
G11 #5e4fa2
G12 #3288bd

You may want to also use the line_dash argument.

In [6]: import bokeh.plotting
   ...: import numpy as np
   ...: import pandas as pd
   ...:
   ...: bokeh.plotting.output_file('cycle_demo.html')
   ...: lines = np.random.random((100, len(w))) + np.arange(24)
   ...: df = pd.DataFrame(lines)
   ...: df.columns = w
   ...:
   ...: line_dash_styles = [[10, 0], [20, 1], [10, 1], [5, 1]]
   ...: p = bokeh.plotting.figure()
   ...: for name, color, line_dash in zip(w, itertools.cycle(Spectral11), itertools.cycle(line_dash_styles)):
   ...:     p.line(np.arange(100), df[name], color=color, legend=name, line_dash=line_dash)
   ...:
   ...: p.legend.location = "top_left"
   ...: bokeh.plotting.show(p)
   ...:

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

+1. Its easier to differentiate Spectral11 colors together with different line_dash in a itertools.cycle, than an inferno(24) where adjacent lines have almost identical colors. I would put more white spaces if possible in the dash design.
@PabloReyes, using the list-of-list syntax I demonstrated, you can customize the dash however you want, even alternating multiple line and dash definitions in the same line; using [4, 2, 6, 4] would do a line for 4 units, blank for 2 units, line for 6 units, then blank for 4 units. When I get a few minutes, I want to adjust my demo so it only cycles the line_dash after going through all the colors (easy with nested loops but I wanted to look up how to do this with itertools).
Also consider the D3 and Colorblind palettes, they work well for categorical data.
2

There are different types of palettes with different number of colors. Check: http://docs.bokeh.org/en/latest/docs/reference/palettes.html. You can choose one of those.

I recommend the ones that are functions, where you can specify the number of colors you want from a big palette like viridis, or inferno.

from bokeh.palettes import inferno
mypalette = inferno(24)

Testing it with random lines in a Jupyter notebook:

import bokeh
import bokeh.plotting
import numpy as np
bokeh.io.output_notebook()

lines = np.random.random((24,100))
p = bokeh.plotting.figure()
mypalette24 = bokeh.palettes.inferno(24)
for i,color in enumerate(mypalette24):
    p.line(np.arange(100),i+lines[i,:],color=color,legend=str(i+1))
p.legend.location = "top_left"
bokeh.io.show(p)

Simple_Example

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.