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

Add bokeh.plotting.gmap to create GMapPlot correctly and easily #5826

Closed
ahamiltonian opened this issue Jan 31, 2017 · 8 comments
Closed

Add bokeh.plotting.gmap to create GMapPlot correctly and easily #5826

ahamiltonian opened this issue Jan 31, 2017 · 8 comments

Comments

@ahamiltonian
Copy link

@ahamiltonian ahamiltonian commented Jan 31, 2017

When using GMapPlot with DataRange1d, the points plotted do not appear in the correct location when the data is updated. See example code below. The solution is to use Range1d. It would be helpful to give a validation error so the developer can be advised to use Range1d instead of DataRange1d.

Thanks,
Andrew

from bokeh.io import output_file, show
from bokeh.models import GMapPlot, GMapOptions, ColumnDataSource, Circle, DataRange1d, WheelZoomTool, Select
from bokeh.plotting import curdoc
from bokeh.layouts import layout, row, widgetbox

# set up map / plot  (my google maps API key: AIzaSyAh1cmN_U6smbyt5uCpMIhttQOYrE4JtLY)
map_options = GMapOptions(lat=49.74, lng=-123.117, map_type="roadmap", zoom=14)
plot = GMapPlot(
    x_range=DataRange1d(), y_range=DataRange1d(), map_options=map_options,
    api_key='PUT YOUR GOOGLE MAPS API KEY HERE'
)

c=['red','green','blue']

# create an initial source object (one color and size on each point)
source = ColumnDataSource( data=dict(   lat = (49.746504,49.735954,49.744864),
                                        lon = (-123.117835,-123.114313,-123.114587),
                                        color = c ) )

# set the circle parameters from the source elements
circle = Circle(x="lon", y="lat", fill_color="color", size=10,  fill_alpha=0.5, line_color=None)

# add the source to the plot as circles
plot.add_glyph(source, circle)

# throw on some tools
plot.add_tools( WheelZoomTool() )


def update(attrname, old, new):

    if color.value == 'RBG': c=['red','green','blue']
    if color.value == 'Greyscale': c=['black','grey','white']
    if color.value == 'CMY': c=['cyan','magenta','yellow']

    # create the source object with the data to be plotted
    source.data=dict(   lat = (49.746504,49.735954,49.744864),
                        lon = (-123.117835,-123.114313,-123.114587),
                        color=c)

    # update the plot
    plot.update()


# add the selectors
color = Select(title='Color', value='None', options=['RBG','Greyscale','CMY'])
color.on_change('value', update)

# add the controls
controls = widgetbox([color], width=200)
layout = row(controls, plot)

curdoc().add_root(layout)
curdoc().title = "My Google Map"
@ahamiltonian
Copy link
Author

@ahamiltonian ahamiltonian commented Jan 31, 2017

Sorry for making a mess of the code, I'm new to posting to GitHub. The 'Insert Code' <> button gave me the mess above (I should have previewed...)

@bryevdv
Copy link
Member

@bryevdv bryevdv commented Jan 31, 2017

No worries, I fixed it up :) FYI code quoting on GH is triple-backticks (on their own lines before/after)

@bryevdv
Copy link
Member

@bryevdv bryevdv commented Jan 31, 2017

@bokeh/dev thoughts? This could be a validation warning, or we could fail harder earlier with an exception... it really doesn't make sense to ever have a DataRange with a GMap, since we are not in the driver's seat. GMaps insist on controlling the ranges directly, and we respond to those changes.

@mattpap
Copy link
Contributor

@mattpap mattpap commented Jan 31, 2017

If it doesn't make sense, don't allow it. There is asserts() method on Property for this task.

@mattpap mattpap added this to the 0.12.5 milestone Jan 31, 2017
@bryevdv
Copy link
Member

@bryevdv bryevdv commented Jan 31, 2017

@mattpap Well, the base Plot just has this:

    x_range = Instance(Range, help="""
    The (default) data range of the horizontal dimension of the plot.
    """)

    y_range = Instance(Range, help="""
    The (default) data range of the vertical dimension of the plot.
    """)

So we'd have to factor everything except ranges out into a PlotBase or something, so that GMapPlot can define those differently. I'm not opposed to that, it's just a chunk of work.

@mattpap
Copy link
Contributor

@mattpap mattpap commented Feb 1, 2017

Not necessarily, GMapPlot could override those properties. This way we don't even need asserts(). Just I doubt this is sound under OOP (edit: given that models are mutable).

@bryevdv
Copy link
Member

@bryevdv bryevdv commented Feb 1, 2017

Possible solution: extend Override functionilty

@bryevdv
Copy link
Member

@bryevdv bryevdv commented Feb 4, 2017

Going further, we can also make a GMapRange1d that has only read-only start and end

@bryevdv bryevdv mentioned this issue Mar 19, 2017
3 of 3 tasks complete
@bryevdv bryevdv changed the title DataRange1d needs warning when used with GMapPlot Need gmap help function to create GMapPlot correctly and esily Mar 21, 2017
@bryevdv bryevdv changed the title Need gmap help function to create GMapPlot correctly and esily Need helper function to create GMapPlot correctly and easily Mar 21, 2017
@bryevdv bryevdv changed the title Need helper function to create GMapPlot correctly and easily Add bokeh.plotting.gmap to create GMapPlot correctly and easily Mar 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

3 participants
You can’t perform that action at this time.