gravedigger
gravedigger

Reputation: 389

Plot semilogx with matplotlib then convert it into Bokeh

I plot a figure containing several curves using matplotlib and then try to convert it into bokeh:

import numpy as np
import matplotlib.pyplot as plt
from bokeh import mpl
from bokeh.plotting import show, output_file


num_plots = 6
colormap = plt.cm.gist_ncar
time = np.random.random_sample((300, 6))
s_strain = np.random.random_sample((300, 6))

def time_s_strain_bokeh(num_plots, colormap, time, s_strain):

    plt.gca().set_color_cycle([colormap(i) for i in np.linspace(0, 0.9, num_plots)])

    plt.figure(2)
    for i in range(0, num_plots):
        plt.plot(time[:,i], s_strain[:,i])
    plt.grid(True)

    # save it to bokeh
    output_file('anywhere.html')
    show(mpl.to_bokeh())    

time_s_strain_bokeh(num_plots, colormap, time, s_strain)

it works fine. However, I want to have a semilogx plot. When I change plt.plot in the "for" loop into plt.semilogx, I have the following error:

UnboundLocalError: local variable 'laxis' referenced before assignment

What can I do to change the x-axis onto log scale?

Upvotes: 2

Views: 868

Answers (2)

bigreddot
bigreddot

Reputation: 34568

As of Bokeh 0.12, partial and incomplete MPL compatibility is provided by the third party mplexporter library, which now appears to be unmaintained. Full (or at least, much more complete) MPL compat support will not happen until the MPL team implements MEP 25. However, implementing MEP 25 is an MPL project task, and the timeline/schedule is entirely outside of the control of the Bokeh project.

The existing MPL compat based on mplexporter is provided "as-is" in case it is useful in the subset of simple situations that it currently works for. My suggestion is to use native Bokeh APIs directly for anything of even moderate complexity.

You can find an example of a semilog plot created using Bokeh APIs here:

http://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#log-scale-axes

Upvotes: 1

Leonardo Portes
Leonardo Portes

Reputation: 56

I'm with the same issue! 1/2 of the solution is this (supose my data is in a Pandas dataframe called pd):

pd.plot(x='my_x_variable', y='my_y_variable) 
p = mpl.to_bokeh()
p.x_mapper_type='log' # I found this property with p.properties_with_values()
show(p)

I edited this answare because I just found part 2/2 of the solution:

  1. When I use just the code above, the plot is semilog (ok!), but the x axis is flipped (mirrored)!!!

  2. The solution I found is explicitly redefine xlim:

    p.x_range.start=0.007 # supose pd['my_x_variable'] starts at 0.007 p.x_range.end=0.17 # supose pd['my_x_variable'] ends at 0.17

With this my plot became identical with the matplotlib original plot. The final code looks like:

pd.plot(x='my_x_variable', y='my_y_variable) 
p = mpl.to_bokeh()
p.x_mapper_type='log' 
p.x_range.start= pd['my_x_variable'].iloc[1] # numpy start at 0, take care!
p.x_range.end= pd['my_x_variable'].iloc[-1]
show(p)

Upvotes: 1

Related Questions