def __init__(self, lat, lng, **kwargs): ''' Args: lat (float): Latitude of the marker. lng (float): Longitude of the marker. Optional: Args: color/c/face_color/fc (str): Marker color. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to red. title (str): Hover-over title of the marker. label (str): Label displayed on the marker. info_window (str): HTML content to be displayed in a pop-up `info window`_. draggable (bool): Whether or not the marker is `draggable`_. Defaults to False. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. .. _info window: https://developers.google.com/maps/documentation/javascript/infowindows .. _draggable: https://developers.google.com/maps/documentation/javascript/markers#draggable ''' color = _get_hex_color( _get_value(kwargs, ['color', 'c', 'face_color', 'fc'], 'red', pop=True)) self._marker_icon = _MarkerIcon(color) self._info_window = _get_value(kwargs, ['info_window'], pop=True) if self._info_window is not None: self._marker_info_window = _MarkerInfoWindow(self._info_window) precision = _get_value(kwargs, ['precision'], 6, pop=True) self._raw_marker = _RawMarker(_format_LatLng(lat, lng, precision), self._marker_icon.get_name(), **kwargs)
def __init__(self, lat, lng, size, **kwargs): ''' Args: lat (float): Latitude of the center of the '+'. lng (float): Longitude of the center of the '+'. size (int): Size of the '+', in meters. Optional: Args: color/c/edge_color/ec (str): Color of the '+''s edge. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/edge_alpha/ea (float): Opacity of the '+''s edge, ranging from 0 to 1. Defaults to 1.0. edge_width/ew (int): Width of the '+''s edge, in pixels. Defaults to 1. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. ''' kwargs.setdefault('edge_color', _get_hex_color(_get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black'))) kwargs.setdefault('edge_alpha', _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'], 1.0)) kwargs.setdefault('edge_width', _get_value(kwargs, ['edge_width', 'ew'], 1)) kwargs.setdefault('precision', _get_value(kwargs, ['precision'], 6)) # TODO: The following generates a '+' in Cartesian frame rather than in lat/lng; avoid this. delta_lat = (size / 1000.0 / _EARTH_RADIUS_IN_KM) * (180.0 / math.pi) delta_lng = delta_lat / math.cos(math.pi * lat / 180.0) self._horizontal_stroke = _Polyline([lat, lat], [lng - delta_lng, lng + delta_lng], **kwargs) self._vertical_stroke = _Polyline([lat - delta_lat, lat + delta_lat], [lng, lng], **kwargs)
def __init__(self, lats, lngs, **kwargs): ''' Args: lats ([float]): Latitudes. lngs ([float]): Longitudes. Optional: Args: color/c/edge_color/ec (str): Color of the polyline. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/edge_alpha/ea (float): Opacity of the polyline, ranging from 0 to 1. Defaults to 1.0. edge_width/ew (int): Width of the polyline, in pixels. Defaults to 1. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. ''' self._color = _get_hex_color( _get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black')) self._edge_alpha = _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'], 1.0) self._edge_width = _get_value(kwargs, ['edge_width', 'ew'], 1) precision = _get_value(kwargs, ['precision'], 6) self._points = [ _format_LatLng(lat, lng, precision) for lat, lng in zip(lats, lngs) ]
def from_geocode(cls, location, **kwargs): ''' Initialize a GoogleMapPlotter object using a location string (instead of a specific lat/lng location). Requires `Geocoding API`_. Args: location (str): Location or address of interest, as a human-readable string. Optional: Args: zoom (int): `Zoom level`_, where 0 is fully zoomed out. Defaults to 13. map_type (str): `Map type`_. apikey (str): Google Maps `API key`_. title (str): Title of the HTML file (as it appears in the browser tab). map_styles ([dict]): `Map styles`_. Requires `Maps JavaScript API`_. tilt (int): `Tilt`_ of the map upon zooming in. scale_control (bool): Whether or not to display the `scale control`_. Defaults to False. fit_bounds (dict): Fit the map to contain the given bounds, as a dict of the form ``{'north': float, 'south': float, 'east': float, 'west': float}``. precision (int): Number of digits after the decimal to round to for the lat/lng center. Defaults to 6. Returns: :class:`GoogleMapPlotter` .. _Geocoding API: https://console.cloud.google.com/marketplace/details/google/geocoding-backend.googleapis.com .. _Zoom level: https://developers.google.com/maps/documentation/javascript/tutorial#zoom-levels .. _Map type: https://developers.google.com/maps/documentation/javascript/maptypes .. _API key: https://developers.google.com/maps/documentation/javascript/get-api-key .. _Map styles: https://developers.google.com/maps/documentation/javascript/style-reference .. _Maps JavaScript API: https://console.cloud.google.com/marketplace/details/google/maps-backend.googleapis.com .. _Tilt: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.tilt .. _scale control: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.scaleControl Usage:: import gmplot apikey = '' # (your API key here) gmap = gmplot.GoogleMapPlotter.from_geocode('Chiyoda City, Tokyo', apikey=apikey) gmap.draw("map.html") .. image:: GoogleMapPlotter.from_geocode.png ''' zoom = _get_value(kwargs, ['zoom'], 13, pop=True) apikey = _get_value(kwargs, ['apikey'], '') return cls(*GoogleMapPlotter.geocode(location, apikey=apikey), zoom=zoom, **kwargs)
def heatmap(self, lats, lngs, **kwargs): ''' Plot a heatmap. Args: lats ([float]): Latitudes. lngs ([float]): Longitudes. Optional: Args: radius (int): Radius of influence for each data point, in pixels. Defaults to 10. gradient ([(int, int, int, float)]): Color gradient of the heatmap, as a list of `RGBA`_ colors. The color order defines the gradient moving towards the center of a point. opacity (float): Opacity of the heatmap, ranging from 0 to 1. Defaults to 0.6. max_intensity (int): Maximum intensity of the heatmap. Defaults to 1. dissipating (bool): True to dissipate the heatmap on zooming, False to disable dissipation. Defaults to True. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. weights ([float]): List of weights corresponding to each data point. Each point has a weight of 1 by default. Specifying a weight of N is equivalent to plotting the same point N times. .. _RGBA: https://www.w3.org/TR/css-color-3/#rgba-color Usage:: import gmplot apikey = '' # (your API key here) gmap = gmplot.GoogleMapPlotter(37.766956, -122.448481, 14, apikey=apikey) attractions = zip(*[ (37.769901, -122.498331), (37.768645, -122.475328), (37.771478, -122.468677), (37.769867, -122.466102), (37.767187, -122.467496), (37.770104, -122.470436) ]) gmap.heatmap( *attractions, radius=40, weights=[5, 1, 1, 1, 3, 1], gradient=[(0, 0, 255, 0), (0, 255, 0, 0.9), (255, 0, 0, 1)] ) gmap.draw('map.html') .. image:: GoogleMapPlotter.heatmap.png ''' if len(lats) != len(lngs): raise ValueError("Number of latitudes and longitudes don't match!") weights = _get_value(kwargs, ['weights']) if weights is not None and len(weights) != len(lats): raise ValueError( "`weights`' length doesn't match the number of points!") self._drawables.append(_Heatmap(lats, lngs, **kwargs))
def __init__(self, lats, lngs, **kwargs): ''' Args: lats ([float]): Latitudes. lngs ([float]): Longitudes. Optional: Args: radius (int): Radius of influence for each data point, in pixels. Defaults to 10. gradient ([(int, int, int, float)]): Color gradient of the heatmap, as a list of `RGBA`_ colors. The color order defines the gradient moving towards the center of a point. opacity (float): Opacity of the heatmap, ranging from 0 to 1. Defaults to 0.6. max_intensity (int): Maximum intensity of the heatmap. Defaults to 1. dissipating (bool): True to dissipate the heatmap on zooming, False to disable dissipation. Defaults to True. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. weights ([float]): List of weights corresponding to each data point. Each point has a weight of 1 by default. Specifying a weight of N is equivalent to plotting the same point N times. .. _RGBA: https://www.w3.org/TR/css-color-3/#rgba-color ''' self._radius = _get_value(kwargs, ['radius'], 10) self._gradient = _get_value(kwargs, ['gradient'], []) self._opacity = _get_value(kwargs, ['opacity'], 0.6) self._max_intensity = _get_value(kwargs, ['max_intensity'], 1) self._dissipating = _get_value(kwargs, ['dissipating'], True) precision = _get_value(kwargs, ['precision'], 6) weights = _get_value(kwargs, ['weights'], [self._DEFAULT_WEIGHT] * len(lats)) self._points = [ self._Point(_format_LatLng(lat, lng, precision), weight) for lat, lng, weight in zip(lats, lngs, weights) ]
def __init__(self, position, icon, **kwargs): ''' Args: position (str): JavaScript code that represents the position of the marker. icon (str): JavaScript code that represents the icon. Optional: Args: title (str): Hover-over title of the marker. label (str): Label displayed on the marker. draggable (bool): Whether or not the marker is draggable. Defaults to False. ''' self._position = position self._icon = icon self._title = _get_value(kwargs, ['title']) self._label = _get_value(kwargs, ['label']) self._draggable = _get_value(kwargs, ['draggable'], False)
def __init__(self, lat, lng, text, **kwargs): ''' Args: lat (float): Latitude of the text label. lng (float): Longitude of the text label. text (str): Text to display. Optional: Args: color/c (str): Text color. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. ''' precision = _get_value(kwargs, ['precision'], 6) self._position = _format_LatLng(lat, lng, precision) self._text = text self._color = _get_hex_color( _get_value(kwargs, ['color', 'c'], 'black')) self._icon = _get_embeddable_image(_COLOR_ICON_PATH % 'clear')
def __init__(self, lat, lng, zoom, **kwargs): ''' Args: lat (float): Latitude of the center of the map. lng (float): Longitude of the center of the map. zoom (int): `Zoom level`_, where 0 is fully zoomed out. Optional: Args: map_type (str): `Map type`_. map_styles ([dict]): `Map styles`_. Requires `Maps JavaScript API`_. tilt (int): `Tilt`_ of the map upon zooming in. scale_control (bool): Whether or not to display the `scale control`_. Defaults to False. fit_bounds (dict): Fit the map to contain the given bounds, as a dict of the form ``{'north': float, 'south': float, 'east': float, 'west': float}``. precision (int): Number of digits after the decimal to round to for the lat/lng center. Defaults to 6. .. _Zoom level: https://developers.google.com/maps/documentation/javascript/tutorial#zoom-levels .. _Map type: https://developers.google.com/maps/documentation/javascript/maptypes .. _Map styles: https://developers.google.com/maps/documentation/javascript/style-reference .. _Maps JavaScript API: https://console.cloud.google.com/marketplace/details/google/maps-backend.googleapis.com .. _Tilt: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.tilt .. _scale control: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.scaleControl ''' precision = _get_value(kwargs, ['precision'], 6) self._center = _format_LatLng(lat, lng, precision) self._zoom = zoom self._map_type = _get_value(kwargs, ['map_type']) self._map_styles = _get_value(kwargs, ['map_styles'], []) self._tilt = _get_value(kwargs, ['tilt']) self._scale_control = _get_value(kwargs, ['scale_control'], False) self._fit_bounds = _get_value(kwargs, ['fit_bounds'])
def __init__(self, lat, lng, radius, **kwargs): ''' Args: lat (float): Latitude of the center of the circle. lng (float): Longitude of the center of the circle. radius (int): Radius of the circle, in meters. Optional: Args: color/c/edge_color/ec (str): Color of the circle's edge. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/edge_alpha/ea (float): Opacity of the circle's edge, ranging from 0 to 1. Defaults to 1.0. edge_width/ew (int): Width of the circle's edge, in pixels. Defaults to 1. color/c/face_color/fc (str): Color of the circle's face. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/face_alpha/fa (float): Opacity of the circle's face, ranging from 0 to 1. Defaults to 0.5. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. ''' precision = _get_value(kwargs, ['precision'], 6) self._center = _format_LatLng(lat, lng, precision) self._radius = radius self._edge_color = _get_hex_color(_get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black')) self._edge_alpha = _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'], 1.0) self._edge_width = _get_value(kwargs, ['edge_width', 'ew'], 1) self._face_color = _get_hex_color(_get_value(kwargs, ['color', 'c', 'face_color', 'fc'], 'black')) self._face_alpha = _get_value(kwargs, ['alpha', 'face_alpha', 'fa'], 0.5)
def __init__(self, origin, destination, **kwargs): ''' Args: origin ((float, float)): Origin, as a latitude/longitude tuple. destination ((float, float)): Destination, as a latitude/longitude tuple. Optional: Args: travel_mode (str): Travel mode. Defaults to 'DRIVING'. waypoints ([(float, float)]): Waypoints. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. ''' precision = _get_value(kwargs, ['precision'], 6) self._origin = _format_LatLng(*origin, precision=precision) self._destination = _format_LatLng(*destination, precision=precision) self._travel_mode = _get_value(kwargs, ['travel_mode'], 'DRIVING').upper() self._waypoints = [ _format_LatLng(*waypoint, precision=precision) for waypoint in _get_value(kwargs, ['waypoints'], []) ]
def __init__(self, url, bounds, **kwargs): ''' Args: url (str): URL of image to overlay. bounds (dict): Image bounds, as a dict of the form ``{'north': float, 'south': float, 'east': float, 'west': float}``. Optional: Args: opacity (float): Opacity of the overlay, ranging from 0 to 1. Defaults to 1.0. ''' self._url = url self._bounds = bounds self._opacity = _get_value(kwargs, ['opacity'], 1.0)
def __init__(self, **kwargs): ''' Optional: Args: color/c (str): Color of the markers to be dropped. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to red. title (str): Hover-over title of the markers to be dropped. label (str): Label displayed on the markers to be dropped. draggable (bool): Whether or not the markers to be dropped are draggable. Defaults to False. ''' color = _get_hex_color( _get_value(kwargs, ['color', 'c'], 'red', pop=True)) self._marker_icon = _MarkerIcon(color) self._marker = _RawMarker('%s.latLng' % self._EVENT_OBJECT_NAME, self._marker_icon.get_name(), **kwargs)
def geocode(location, **kwargs): ''' Return the lat/lng coordinates of a location string. Requires `Geocoding API`_. Args: location (str): Location or address of interest, as a human-readable string. Optional: Args: apikey (str): Google Maps `API key`_. .. _Geocoding API: https://console.cloud.google.com/marketplace/details/google/geocoding-backend.googleapis.com .. _API key: https://developers.google.com/maps/documentation/javascript/get-api-key Returns: (float, float): Latitude/longitude coordinates of the given location string. Usage:: import gmplot apikey = '' # (your API key here) location = gmplot.GoogleMapPlotter.geocode('Versailles, France', apikey=apikey) print(location) .. code-block:: -> (48.801408, 2.130122) ''' apikey = _get_value(kwargs, ['apikey'], '') geocode = requests.get( 'https://maps.googleapis.com/maps/api/geocode/json?address="%s"&key=%s' % (location, apikey)) geocode = json.loads(geocode.text) if geocode.get('error_message', ''): raise GoogleAPIError(geocode['error_message']) latlng_dict = geocode['results'][0]['geometry']['location'] return latlng_dict['lat'], latlng_dict['lng']
def __init__(self, shape, lat, lng, size, **kwargs): ''' Args: shape (str): Shape of the symbol, as 'o', 'x', or '+'. lat (float): Latitude of the center of the symbol. lng (float): Longitude of the center of the symbol. size (int): Size of the symbol, in meters. Optional: Args: color/c/edge_color/ec (str): Color of the symbol's edge. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/edge_alpha/ea (float): Opacity of the symbol's edge, ranging from 0 to 1. Defaults to 1.0. edge_width/ew (int): Width of the symbol's edge, in pixels. Defaults to 1. color/c/face_color/fc (str): Color of the symbol's face. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/face_alpha/fa (float): Opacity of the symbol's face, ranging from 0 to 1. Defaults to 0.5. precision (int): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. ''' kwargs.setdefault( 'edge_color', _get_hex_color( _get_value(kwargs, ['color', 'c', 'edge_color', 'ec'], 'black'))) kwargs.setdefault( 'edge_alpha', _get_value(kwargs, ['alpha', 'edge_alpha', 'ea'], 1.0)) kwargs.setdefault('edge_width', _get_value(kwargs, ['edge_width', 'ew'], 1)) kwargs.setdefault( 'face_color', _get_hex_color( _get_value(kwargs, ['color', 'c', 'face_color', 'fc'], 'black'))) kwargs.setdefault( 'face_alpha', _get_value(kwargs, ['alpha', 'face_alpha', 'fa'], 0.5)) kwargs.setdefault('precision', _get_value(kwargs, ['precision'], 6)) self._symbol = self._SHAPES[shape](lat, lng, size, **kwargs)
def __init__(self, lat, lng, zoom, **kwargs): ''' Args: lat (float): Latitude of the center of the map. lng (float): Longitude of the center of the map. zoom (int): `Zoom level`_, where 0 is fully zoomed out. Optional: Args: map_type (str): `Map type`_. apikey (str): Google Maps `API key`_. title (str): Title of the HTML file (as it appears in the browser tab). map_styles ([dict]): `Map styles`_. Requires `Maps JavaScript API`_. tilt (int): `Tilt`_ of the map upon zooming in. scale_control (bool): Whether or not to display the `scale control`_. Defaults to False. fit_bounds (dict): Fit the map to contain the given bounds, as a dict of the form ``{'north': float, 'south': float, 'east': float, 'west': float}``. precision (int): Number of digits after the decimal to round to for the lat/lng center. Defaults to 6. .. _Zoom level: https://developers.google.com/maps/documentation/javascript/tutorial#zoom-levels .. _Map type: https://developers.google.com/maps/documentation/javascript/maptypes .. _API key: https://developers.google.com/maps/documentation/javascript/get-api-key .. _Map styles: https://developers.google.com/maps/documentation/javascript/style-reference .. _Maps JavaScript API: https://console.cloud.google.com/marketplace/details/google/maps-backend.googleapis.com .. _Tilt: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.tilt .. _scale control: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.scaleControl Usage:: import gmplot apikey = '' # (your API key here) gmap = gmplot.GoogleMapPlotter(37.7670, -122.4385, 13, apikey=apikey, map_type='hybrid') gmap.draw("map.html") .. image:: GoogleMapPlotter.png Further customization and `styling`_:: import gmplot apikey = '' # (your API key here) bounds = {'north': 37.967, 'south': 37.567, 'east': -122.238, 'west': -122.638} map_styles = [ { 'featureType': 'all', 'stylers': [ {'saturation': -80}, {'lightness': 30}, ] } ] gmplot.GoogleMapPlotter( 37.766956, -122.438481, 13, apikey=apikey, map_styles=map_styles, scale_control=True, fit_bounds=bounds ).draw("map.html") .. _styling: https://developers.google.com/maps/documentation/javascript/styling .. image:: GoogleMapPlotter_Styled.png ''' self._apikey = _get_value(kwargs, ['apikey'], '', pop=True) self._title = _get_value(kwargs, ['title'], 'Google Maps - gmplot', pop=True) self._map = _Map(lat, lng, zoom, **kwargs) self._drawables = [] self._markers = [] self._marker_dropper = None
def scatter(self, lats, lngs, **kwargs): ''' Plot a collection of points. Args: lats ([float]): Latitudes. lngs ([float]): Longitudes. Optional: Args: marker (bool or [bool]): True to plot points as markers, False to plot them as symbols. Defaults to True. title (str or [str]): Hover-over title of each point (markers only). label (str or [str]): Label displayed on each point (markers only). info_window (str or [str]): HTML content to be displayed in each point's pop-up `info window`_ (markers only). draggable (bool): Whether or not each point is `draggable`_ (markers only). Defaults to False. symbol (str or [str]): Shape of each point, as 'o', 'x', or '+' (symbols only). Defaults to 'o'. size/s (int or [int]): Size of each point, in meters (symbols only). Defaults to 40. color/c/edge_color/ec (str or [str]): Color of each point's edge (symbols only). Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/edge_alpha/ea (float or [float]): Opacity of each point's edge, ranging from 0 to 1 (symbols only). Defaults to 1.0. edge_width/ew (int or [int]): Width of each point's edge, in pixels (symbols only). Defaults to 1. color/c/face_color/fc (str or [str]): Color of each point's face. Can be hex ('#00FFFF'), named ('cyan'), or matplotlib-like ('c'). Defaults to black. alpha/face_alpha/fa (float or [float]): Opacity of each point's face, ranging from 0 to 1 (symbols only). Defaults to 0.3. precision (int or [int]): Number of digits after the decimal to round to for lat/lng values. Defaults to 6. .. _info window: https://developers.google.com/maps/documentation/javascript/infowindows .. _draggable: https://developers.google.com/maps/documentation/javascript/markers#draggable Usage:: import gmplot apikey = '' # (your API key here) gmap = gmplot.GoogleMapPlotter(37.766956, -122.479481, 15, apikey=apikey) attractions = zip(*[ (37.769901, -122.498331), (37.768645, -122.475328), (37.771478, -122.468677), (37.769867, -122.466102), (37.767187, -122.467496), (37.770104, -122.470436) ]) gmap.scatter( *attractions, color=['red', 'orange', 'yellow', 'green', 'blue', 'purple'], s=60, ew=2, marker=[True, True, False, True, False, False], symbol=[None, None, 'o', None, 'x', '+'], title=['First', 'Second', None, 'Third', None, None], label=['A', 'B', 'C', 'D', 'E', 'F'] ) gmap.draw('map.html') .. image:: GoogleMapPlotter.scatter.png ''' ARG_MAP = { 'marker': _ArgInfo(['marker'], True), 'title': _ArgInfo(['title'], None), 'label': _ArgInfo(['label'], None), 'info_window': _ArgInfo(['info_window'], None), 'draggable': _ArgInfo(['draggable'], False), 'symbol': _ArgInfo(['symbol'], 'o'), 'size': _ArgInfo(['size', 's'], 40), 'edge_color': _ArgInfo(['color', 'c', 'edge_color', 'ec'], 'black'), 'edge_alpha': _ArgInfo(['alpha', 'edge_alpha', 'ea'], 1.0), 'edge_width': _ArgInfo(['edge_width', 'ew'], 1), 'face_color': _ArgInfo(['color', 'c', 'face_color', 'fc'], 'black'), 'face_alpha': _ArgInfo(['alpha', 'face_alpha', 'fa'], 0.3), 'precision': _ArgInfo(['precision'], 6) } # This links the draw-related settings to the arguments passed into this function. # Note that some settings can be set through more than one argument. # If no arguments are passed in for a given setting, its defined default is used. if len(lats) != len(lngs): raise ValueError("Number of latitudes and longitudes don't match!") # For each setting... settings = dict() for setting_name, arg_info in ARG_MAP.items(): # ...attempt to set it from kwargs (if the value isn't a list, expand it into one): argument_name, value = _get_value(kwargs, arg_info.arguments, arg_info.default, get_key=True) settings[setting_name] = value if isinstance( value, list) else [value] * len(lats) # ...ensure that its length matches the number of points: if len(settings[setting_name]) != len(lats): raise ValueError( "`%s`'s length doesn't match the number of points!" % argument_name) # For each point, plot a marker or symbol with its corresponding settings: for i, location in enumerate(zip(lats, lngs)): point_settings = { setting_name: value[i] for (setting_name, value) in settings.items() } if point_settings.pop('marker'): self.marker(*location, **point_settings) else: shape = point_settings.pop('symbol') if not _Symbol.is_valid(shape): raise InvalidSymbolError( "Symbol '%s' is not implemented." % shape) self._drawables.append( _Symbol(shape, *location, size=point_settings.pop('size'), **point_settings))