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

Comments

Projects
None yet
3 participants
@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

This comment has been minimized.

Show comment
Hide comment
@ahamiltonian

ahamiltonian 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...)

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

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Jan 31, 2017

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Jan 31, 2017

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap Jan 31, 2017

Contributor

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

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Jan 31, 2017

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap Feb 1, 2017

Contributor

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).

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Feb 1, 2017

Member

Possible solution: extend Override functionilty

Member

bryevdv commented Feb 1, 2017

Possible solution: extend Override functionilty

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Feb 4, 2017

Member

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

Member

bryevdv commented Feb 4, 2017

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

@bryevdv bryevdv referenced this issue Mar 19, 2017

Merged

Bryanv/2940 gmap axes #6017

3 of 3 tasks complete

@bryevdv bryevdv closed this in #6017 Mar 20, 2017

@bryevdv bryevdv changed the title from DataRange1d needs warning when used with GMapPlot to Need gmap help function to create GMapPlot correctly and esily Mar 21, 2017

@bryevdv bryevdv changed the title from Need gmap help function to create GMapPlot correctly and esily to Need helper function to create GMapPlot correctly and easily Mar 21, 2017

@bryevdv bryevdv changed the title from Need helper function to create GMapPlot correctly and easily to 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