Reputation: 398
I first render the figure in notebook, then I save it in svg form. The figure display in notebook is correct, but the saved svg is missing some markers.
#!/usr/bin/python3
import pandas as pd
import numpy as np
import math
from bokeh.plotting import figure, show, ColumnDataSource, save, output_file, reset_output
from bokeh.models import HoverTool, Legend
from bokeh.layouts import gridplot
import colorsys # needed for generating N equally extinguishable colors
from itertools import cycle
d = {'Sex': ['male', 'male','male','male', 'male','male','female','female','female','female','female','female'], 'age': [20, 20,20, 25,25,25,20, 20,20,25,25,25], 'working_hours': [20,30,40,20,30,40,20,30,40,20,30,40],'income': [1000, 2000,3000,1500, 2500,3500,1100, 2100,3100,1300, 2300,3300] }
values = pd.DataFrame(data=d)
x_var = 'working_hours'
x_var_dimension = 'H'
y_var = 'income'
y_var_dimension = 'Dollars'
hover = HoverTool(tooltips=[("data (x,y)", "(@x, @y)")])
TOOLS=[hover]
p= figure(width=1200, height=600,tools=TOOLS, x_axis_type='linear', x_axis_label='%s [%s]'%(x_var, x_var_dimension),y_axis_label='%s [%s]'%(y_var, y_var_dimension))
nr_expressions_row_col=9
figs_array_row_col = []
figs_row_row_col=[]
legend_its_row_col = []
legend_its_row_col_renderer = []
loop_count = 0;
markers = ['circle', 'square', 'triangle', 'asterisk', 'circle_x', 'square_x', 'inverted_triangle', 'x', 'circle_cross', 'square_cross', 'diamond', 'cross']
pool = cycle(markers)
for key, group in values.groupby(['Sex']):
for key_sub1, group_sub1 in group.groupby(['age']):
loop_count+=1
x_data = group_sub1[x_var].values;
y_data = group_sub1[y_var].values
(color_r,color_g,color_b) = colorsys.hsv_to_rgb(loop_count*1.0/nr_expressions_row_col, 1, 1)
plot_row_col_line = p.line(x_data, y_data,line_color=(int(255*color_r),int(255*color_g),int(255*color_b)))
plot_row_col_glyph = p.scatter(x_data, y_data, color=(int(255*color_r),int(255*color_g),int(255*color_b)), size=10, marker=next(pool))
legend_its_row_col.append(("%s %s"%(key,key_sub1), [plot_row_col_line, plot_row_col_glyph]))
legend_row_col = Legend(items = legend_its_row_col, location=(0,0))
legend_row_col.click_policy = 'hide'
legend_row_col.background_fill_alpha = 0
p.add_layout(legend_row_col, 'left')
figs_row_row_col.append(p)
figs_array_row_col.append(figs_row_row_col)
grid_row_col = gridplot(figs_array_row_col)
reset_output()
output_notebook()
show(grid_row_col)
p.output_backend = "svg"
export_svgs(grid_row_col, filename="%s/"%'.' + "_" +"stackoverflow.svg")
Here is what I see in notebook, which is what I expected:
And here is what I see when opening '_stackoverflow.svg'
The legend color for 'female 25' and 'male 20' is partially black. (the marker part) and 'female 20' is missing both marker and its legend.
Upvotes: 4
Views: 276
Reputation: 546
The reason you are seeing different colors in the notebook and the exported image is that they use two different backends. You set the backend to SVG just before exporting it in the last line. Therefore, though the exported image uses SVG backend, the image on the notebook uses the default backend, which is canvas.
The backend can be set with two options: one you used and one where you add output_backend="svg"
argument when you call figure
. That is, replacing
p= figure(width=1200, height=600,tools=TOOLS, x_axis_type='linear', x_axis_label='%s [%s]'%(x_var, x_var_dimension),y_axis_label='%s [%s]'%(y_var, y_var_dimension))
with
p= figure(width=1200, height=600,tools=TOOLS, x_axis_type='linear', x_axis_label='%s [%s]'%(x_var, x_var_dimension),y_axis_label='%s [%s]'%(y_var, y_var_dimension), output_backend="svg")
.
Now you will see the same issue you see in the exported image on you notebook image. It seems like this is a bug in the SVG backend, and most likely they are working on that. Unfortunately there is no expected date for the bug fix.
Upvotes: 1