text:
---
layout: post
author: Ding
title:  "Cartopy Gallery"
date:   2017-09-15
categories: Python
tags:
- Python
- cartopy
- matplotlib
- visualising
---

* content
{:toc}

> cartopy 官网上的一些样例程序.

## Cartopy Gallery

### always_circular_stereo example

```python
import matplotlib.path as mpath
import matplotlib.pyplot as plt
import numpy as np

import cartopy.crs as ccrs
import cartopy.feature

def main():
    fig = plt.figure(figsize=[10, 5])
    ax1 = plt.subplot(1, 2, 1, projection=ccrs.SouthPolarStereo())
    ax2 = plt.subplot(1, 2, 2, projection=ccrs.SouthPolarStereo(),
                      sharex=ax1, sharey=ax1)
    fig.subplots_adjust(bottom=0.05, top=0.95,
                        left=0.04, right=0.95, wspace=0.02)

    # Limit the map to -60 degrees latitude and below.
    ax1.set_extent([-180, 180, -90, -60], ccrs.PlateCarree())

    ax1.add_feature(cartopy.feature.LAND)
    ax1.add_feature(cartopy.feature.OCEAN)

    ax1.gridlines()
    ax2.gridlines()

    ax2.add_feature(cartopy.feature.LAND)
    ax2.add_feature(cartopy.feature.OCEAN)

    # Compute a circle in axes coordinates, which we can use as a boundary
    # for the map. We can pan/zoom as much as we like - the boundary will be
    # permanently circular.
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)

    ax2.set_boundary(circle, transform=ax2.transAxes)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_1_0.png)

### arrows example

```python
import matplotlib.pyplot as plt
import numpy as np

import cartopy
import cartopy.crs as ccrs

def sample_data(shape=(20, 30)):
    """
    Returns ``(x, y, u, v, crs)`` of some vector data
    computed mathematically. The returned crs will be a rotated
    pole CRS, meaning that the vectors will be unevenly spaced in
    regular PlateCarree space.

    """
    crs = ccrs.RotatedPole(pole_longitude=177.5, pole_latitude=37.5)

    x = np.linspace(311.9, 391.1, shape[1])
    y = np.linspace(-23.6, 24.8, shape[0])

    x2d, y2d = np.meshgrid(x, y)
    u = 10 * (2 * np.cos(2 * np.deg2rad(x2d) + 3 * np.deg2rad(y2d + 30)) ** 2)
    v = 20 * np.cos(6 * np.deg2rad(x2d))

    return x, y, u, v, crs

def main():
    ax = plt.axes(projection=ccrs.Orthographic(-10, 45))

    ax.add_feature(cartopy.feature.OCEAN, zorder=0)
    ax.add_feature(cartopy.feature.LAND, zorder=0, edgecolor='black')

    ax.set_global()
    ax.gridlines()

    x, y, u, v, vector_crs = sample_data()
    ax.quiver(x, y, u, v, transform=vector_crs)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_3_0.png)

### barbs example

```python
import matplotlib.pyplot as plt

import cartopy.crs as ccrs
from cartopy.examples.arrows import sample_data

def main():
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([-90, 75, 10, 60])
    ax.stock_img()
    ax.coastlines()

    x, y, u, v, vector_crs = sample_data(shape=(10, 14))
    ax.barbs(x, y, u, v, length=5,
             sizes=dict(emptybarb=0.25, spacing=0.2, height=0.5),
             linewidth=0.95, transform=vector_crs)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_5_0.png)

### Plotting the Aurora Forecast from NOAA on Orthographic Polar Projection

```python
"""
Plotting the Aurora Forecast from NOAA on Orthographic Polar Projection
-----------------------------------------------------------------------

The National Oceanic and Atmospheric Administration (NOAA) monitors the
solar wind conditions using the ACE spacecraft orbiting close to the L1
Lagrangian point of the Sun-Earth system. This data is fed into the
OVATION-Prime model to forecast the probability of visible aurora at
various locations on Earth. Every five minutes a new forecast is
published for the coming 30 minutes. The data is provided as a
1024 by 512 grid of probabilities in percent of visible aurora. The
data spaced equally in degrees from -180 to 180 and -90 to 90.

"""
try:
    from urllib2 import urlopen
except ImportError:
    from urllib.request import urlopen

from io import StringIO

import numpy as np
from datetime import datetime
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import matplotlib.patches as patches

def aurora_forecast():
    """
    Gets the latest Aurora Forecast from http://swpc.noaa.gov.

    Returns
    -------
    img : numpy array
        The pixels of the image in a numpy array.
    img_proj : cartopy CRS
        The rectangular coordinate system of the image.
    img_extent : tuple of floats
        The extent of the image ``(x0, y0, x1, y1)`` referenced in
        the ``img_proj`` coordinate system.
    origin : str
        The origin of the image to be passed through to matplotlib's imshow.
    dt : datetime
        Time of forecast validity.

    """

    # GitHub gist to download the example data from
    url = ('https://gist.githubusercontent.com/belteshassar/'
           'c7ea9e02a3e3934a9ddc/raw/aurora-nowcast-map.txt')
    # To plot the current forecast instead, uncomment the following line
    # url = 'http://services.swpc.noaa.gov/text/aurora-nowcast-map.txt'

    response_text = StringIO(urlopen(url).read().decode('utf-8'))
    img = np.loadtxt(response_text)
    # Read forecast date and time
    response_text.seek(0)
    for line in response_text:
        if line.startswith('Product Valid At:', 2):
            dt = datetime.strptime(line[-17:-1], '%Y-%m-%d %H:%M')

    img_proj = ccrs.PlateCarree()
    img_extent = (-180, 180, -90, 90)
    return img, img_proj, img_extent, 'lower', dt

def aurora_cmap():
    """Return a colormap with aurora like colors"""
    stops = {'red': [(0.00, 0.1725, 0.1725),
                     (0.50, 0.1725, 0.1725),
                     (1.00, 0.8353, 0.8353)],

             'green': [(0.00, 0.9294, 0.9294),
                       (0.50, 0.9294, 0.9294),
                       (1.00, 0.8235, 0.8235)],

             'blue': [(0.00, 0.3843, 0.3843),
                      (0.50, 0.3843, 0.3843),
                      (1.00, 0.6549, 0.6549)],

             'alpha': [(0.00, 0.0, 0.0),
                       (0.50, 1.0, 1.0),
                       (1.00, 1.0, 1.0)]}

    return LinearSegmentedColormap('aurora', stops)

def sun_pos(dt=None):
    """This function computes a rough estimate of the coordinates for
    the point on the surface of the Earth where the Sun is directly
    overhead at the time dt. Precision is down to a few degrees. This
    means that the equinoxes (when the sign of the latitude changes)
    will be off by a few days.

    The function is intended only for visualization. For more precise
    calculations consider for example the PyEphem package.

    Parameters
    ----------
        dt: datetime
            Defaults to datetime.utcnow()

    Returns
    -------
        lat, lng: tuple of floats
            Approximate coordinates of the point where the sun is
            in zenith at the time dt.
    """
    if dt is None:
        dt = datetime.utcnow()

    axial_tilt = 23.4
    ref_solstice = datetime(2016, 6, 21, 22, 22)
    days_per_year = 365.2425
    seconds_per_day = 24*60*60.0

    days_since_ref = (dt - ref_solstice).total_seconds()/seconds_per_day
    lat = axial_tilt*np.cos(2*np.pi*days_since_ref/days_per_year)
    sec_since_midnight = (dt - datetime(dt.year, dt.month, dt.day)).seconds
    lng = -(sec_since_midnight/seconds_per_day - 0.5)*360
    return lat, lng

def fill_dark_side(ax, time=None, *args, **kwargs):
    """
    Plot a fill on the dark side of the planet (without refraction).

    Parameters
    ----------
        ax : matplotlib axes
            The axes to plot on.
        time : datetime
            The time to calculate terminator for. Defaults to datetime.utcnow()
        **kwargs :
            Passed on to Matplotlib's ax.fill()

    """
    lat, lng = sun_pos(time)
    pole_lng = lng
    if lat > 0:
        pole_lat = -90 + lat
        central_rot_lng = 180
    else:
        pole_lat = 90 + lat
        central_rot_lng = 0

    rotated_pole = ccrs.RotatedPole(pole_latitude=pole_lat,
                                    pole_longitude=pole_lng,
                                    central_rotated_longitude=central_rot_lng)

    x = np.empty(360)
    y = np.empty(360)
    x[:180] = -90
    y[:180] = np.arange(-90, 90.)
    x[180:] = 90
    y[180:] = np.arange(90, -90., -1)

    ax.fill(x, y, transform=rotated_pole, **kwargs)

def main():
    fig = plt.figure(figsize=[10, 5])

    # We choose to plot in an Orthographic projection as it looks natural
    # and the distortion is relatively small around the poles where
    # the aurora is most likely.

    # ax1 for Northern Hemisphere
    ax1 = plt.subplot(1, 2, 1, projection=ccrs.Orthographic(0, 90))

    # ax2 for Southern Hemisphere
    ax2 = plt.subplot(1, 2, 2, projection=ccrs.Orthographic(180, -90))

    img, crs, extent, origin, dt = aurora_forecast()

    for ax in [ax1, ax2]:
        ax.coastlines(zorder=3)
        ax.stock_img()
        ax.gridlines()
        fill_dark_side(ax, time=dt, color='black', alpha=0.75)
        ax.imshow(img, vmin=0, vmax=100, transform=crs,
                  extent=extent, origin=origin, zorder=2,
                  cmap=aurora_cmap())

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_7_0.png)

### axes_grid_basic example

```python
"""
Using Cartopy and AxesGrid toolkit
----------------------------------

This example demonstrates how to use cartopy `GeoAxes` with
`AxesGrid` from the `mpl_toolkits.axes_grid1`.
The script constructs an `axes_class` kwarg with Plate Carree projection
and passes it to the `AxesGrid` instance. The `AxesGrid` built-in
labelling is switched off, and instead a standard procedure
of creating grid lines is used. Then some fake data is plotted.
"""
import cartopy.crs as ccrs
from cartopy.mpl.geoaxes import GeoAxes
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import AxesGrid
import numpy as np

def sample_data_3d(shape):
    """Returns `lons`, `lats`, `times` and fake `data`"""
    ntimes, nlats, nlons = shape
    lats = np.linspace(-np.pi / 2, np.pi / 2, nlats)
    lons = np.linspace(0, 2 * np.pi, nlons)
    lons, lats = np.meshgrid(lons, lats)
    wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons)
    mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2)

    lats = np.rad2deg(lats)
    lons = np.rad2deg(lons)
    data = wave + mean

    times = np.linspace(-1, 1, ntimes)
    new_shape = data.shape + (ntimes, )
    data = np.rollaxis(data.repeat(ntimes).reshape(new_shape), -1)
    data *= times[:, np.newaxis, np.newaxis]

    return lons, lats, times, data

def main():
    projection = ccrs.PlateCarree()
    axes_class = (GeoAxes,
                  dict(map_projection=projection))

    lons, lats, times, data = sample_data_3d((6, 73, 145))

    fig = plt.figure(figsize=(8,10))
    axgr = AxesGrid(fig, 111, axes_class=axes_class,
                    nrows_ncols=(3, 2),
                    axes_pad=0.6,
                    cbar_location='right',
                    cbar_mode='single',
                    cbar_pad=0.2,
                    cbar_size='3%',
                    label_mode='')  # note the empty label_mode

    for i, ax in enumerate(axgr):
        ax.coastlines()
        ax.set_xticks(np.linspace(-180, 180, 5), crs=projection)
        ax.set_yticks(np.linspace(-90, 90, 5), crs=projection)
        lon_formatter = LongitudeFormatter(zero_direction_label=True)
        lat_formatter = LatitudeFormatter()
        ax.xaxis.set_major_formatter(lon_formatter)
        ax.yaxis.set_major_formatter(lat_formatter)

        p = ax.contourf(lons, lats, data[i, ...],
                        transform=projection,
                        cmap='RdBu')

    axgr.cbar_axes[0].colorbar(p)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_9_0.png)

### Map tile acquisition

```python
# -*- coding: utf-8 -*-
"""
Map tile acquisition
--------------------

Demonstrates cartopy's ability to draw map tiles which are downloaded on
demand from the Stamen tile server. Internally these tiles are then combined
into a single image and displayed in the cartopy GeoAxes.

"""
import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy

import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt

def main():
    # Create a Stamen Terrain instance.
    stamen_terrain = cimgt.StamenTerrain()

    # Create a GeoAxes in the tile's projection.
    ax = plt.axes(projection=stamen_terrain.crs)

    # Limit the extent of the map to a small longitude/latitude range.
    ax.set_extent([-22, -15, 63, 65])

    # Add the Stamen data at zoom level 8.
    ax.add_image(stamen_terrain, 8)

    # Add a marker for the Eyjafjallajökull volcano.
    plt.plot(-19.613333, 63.62, marker='o', color='red', markersize=12,
             alpha=0.7, transform=ccrs.Geodetic())

    # Use the cartopy interface to create a matplotlib transform object
    # for the Geodetic coordinate system. We will use this along with
    # matplotlib's offset_copy function to define a coordinate system which
    # translates the text by 25 pixels to the left.
    geodetic_transform = ccrs.Geodetic()._as_mpl_transform(ax)
    text_transform = offset_copy(geodetic_transform, units='dots', x=-25)

    # Add text 25 pixels to the left of the volcano.
    plt.text(-19.613333, 63.62, u'Eyjafjallajökull',
             verticalalignment='center', horizontalalignment='right',
             transform=text_transform,
             bbox=dict(facecolor='sandybrown', alpha=0.5, boxstyle='round'))
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_11_0.png)

### favicon example

```python
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.textpath
import matplotlib.patches
from matplotlib.font_manager import FontProperties
import numpy as np

def main():
    plt.figure(figsize=[8, 8])
    ax = plt.axes(projection=ccrs.SouthPolarStereo())

    ax.coastlines()
    ax.gridlines()

    im = ax.stock_img()

    def on_draw(event=None):
        """
        Hooks into matplotlib's event mechanism to define the clip path of the
        background image.

        """
        # Clip the image to the current background boundary.
        im.set_clip_path(ax.background_patch.get_path(),
                         transform=ax.background_patch.get_transform())

    # Register the on_draw method and call it once now.
    plt.gcf().canvas.mpl_connect('draw_event', on_draw)
    on_draw()

    # Generate a matplotlib path representing the character "C".
    fp = FontProperties(family='Bitstream Vera Sans', weight='bold')
    logo_path = matplotlib.textpath.TextPath((-4.5e7, -3.7e7),
                                             'C', size=1, prop=fp)

    # Scale the letter up to an appropriate X and Y scale.
    logo_path._vertices *= np.array([103250000, 103250000])

    # Add the path as a patch, drawing black outlines around the text.
    patch = matplotlib.patches.PathPatch(logo_path, facecolor='white',
                                         edgecolor='black', linewidth=10,
                                         transform=ccrs.SouthPolarStereo())
    ax.add_patch(patch)
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_13_0.png)

### feature_creation example

```python
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from matplotlib.offsetbox import AnchoredText

def main():
    fig = plt.figure(figsize=(8,8))
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([80, 170, -45, 30])

    # Put a background image on for nice sea rendering.
    ax.stock_img()

    # Create a feature for States/Admin 1 regions at 1:50m from Natural Earth
    states_provinces = cfeature.NaturalEarthFeature(
        category='cultural',
        name='admin_1_states_provinces_lines',
        scale='50m',
        facecolor='none')

    SOURCE = 'Natural Earth'
    LICENSE = 'public domain'

    ax.add_feature(cfeature.LAND)
    ax.add_feature(cfeature.COASTLINE)
    ax.add_feature(states_provinces, edgecolor='gray')

    # Add a text annotation for the license information to the
    # the bottom right corner.
    text = AnchoredText(r'$\mathcircled{{c}}$ {}; license: {}'
                        ''.format(SOURCE, LICENSE),
                        loc=4, prop={'size': 12}, frameon=True)
    ax.add_artist(text)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_15_0.png)

### features example

```python
import cartopy
import matplotlib.pyplot as plt

def main():

    fig = plt.figure(figsize=(8,8))
    ax = plt.axes(projection=cartopy.crs.PlateCarree())

    ax.add_feature(cartopy.feature.LAND)
    ax.add_feature(cartopy.feature.OCEAN)
    ax.add_feature(cartopy.feature.COASTLINE)
    ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
    ax.add_feature(cartopy.feature.LAKES, alpha=0.5)
    ax.add_feature(cartopy.feature.RIVERS)

    ax.set_extent([-20, 60, -40, 40])

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_17_0.png)

### Reprojecting images from a Geostationary projection

```python
"""
Reprojecting images from a Geostationary projection
---------------------------------------------------

This example demonstrates Cartopy's ability to project images into the desired
projection on-the-fly. The image itself is retrieved from a URL and is loaded
directly into memory without storing it intermediately into a file. It
represents pre-processed data from the Spinning Enhanced Visible and Infrared
Imager onboard Meteosat Second Generation, which has been put into an image in
the data's native Geostationary coordinate system - it is then projected by
cartopy into a global Miller map.

"""
try:
    from urllib2 import urlopen
except ImportError:
    from urllib.request import urlopen
from io import BytesIO

import cartopy.crs as ccrs
import matplotlib.pyplot as plt

def geos_image():
    """
    Return a specific SEVIRI image by retrieving it from a github gist URL.

    Returns
    -------
    img : numpy array
        The pixels of the image in a numpy array.
    img_proj : cartopy CRS
        The rectangular coordinate system of the image.
    img_extent : tuple of floats
        The extent of the image ``(x0, y0, x1, y1)`` referenced in
        the ``img_proj`` coordinate system.
    origin : str
        The origin of the image to be passed through to matplotlib's imshow.

    """
    url = ('https://gist.github.com/pelson/5871263/raw/'
           'EIDA50_201211061300_clip2.png')
    img_handle = BytesIO(urlopen(url).read())
    img = plt.imread(img_handle)
    img_proj = ccrs.Geostationary(satellite_height=35786000)
    img_extent = (-5500000, 5500000, -5500000, 5500000)
    return img, img_proj, img_extent, 'upper'

def main():
    ax = plt.axes(projection=ccrs.Miller())
    ax.coastlines()
    ax.set_global()
    img, crs, extent, origin = geos_image()
    plt.imshow(img, transform=crs, extent=extent, origin=origin, cmap='gray')
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_19_1.png)

### global_map example

```python
import matplotlib.pyplot as plt

import cartopy.crs as ccrs

def main():
    fig = plt.figure(figsize=(8,8))
    ax = plt.axes(projection=ccrs.Robinson())

    # make the map global rather than have it zoom in to
    # the extents of any plotted data
    ax.set_global()

    ax.stock_img()
    ax.coastlines()

    plt.plot(-0.08, 51.53, 'o', transform=ccrs.PlateCarree())
    plt.plot([-0.08, 132], [51.53, 43.17], transform=ccrs.PlateCarree())
    plt.plot([-0.08, 132], [51.53, 43.17], transform=ccrs.Geodetic())

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_21_0.png)

### hurricane_katrina example

```python
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import shapely.geometry as sgeom

import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader

def sample_data():
    """
    Returns a list of latitudes and a list of longitudes (lons, lats)
    for Hurricane Katrina (2005).

    The data was originally sourced from the HURDAT2 dataset from AOML/NOAA:
    http://www.aoml.noaa.gov/hrd/hurdat/newhurdat-all.html on 14th Dec 2012.

    """
    lons = [-75.1, -75.7, -76.2, -76.5, -76.9, -77.7, -78.4, -79.0,
            -79.6, -80.1, -80.3, -81.3, -82.0, -82.6, -83.3, -84.0,
            -84.7, -85.3, -85.9, -86.7, -87.7, -88.6, -89.2, -89.6,
            -89.6, -89.6, -89.6, -89.6, -89.1, -88.6, -88.0, -87.0,
            -85.3, -82.9]

    lats = [23.1, 23.4, 23.8, 24.5, 25.4, 26.0, 26.1, 26.2, 26.2, 26.0,
            25.9, 25.4, 25.1, 24.9, 24.6, 24.4, 24.4, 24.5, 24.8, 25.2,
            25.7, 26.3, 27.2, 28.2, 29.3, 29.5, 30.2, 31.1, 32.6, 34.1,
            35.6, 37.0, 38.6, 40.1]

    return lons, lats

def main():
    ax = plt.axes([0, 0, 1, 1],
                  projection=ccrs.LambertConformal())

    ax.set_extent([-125, -66.5, 20, 50], ccrs.Geodetic())

    shapename = 'admin_1_states_provinces_lakes_shp'
    states_shp = shpreader.natural_earth(resolution='110m',
                                         category='cultural', name=shapename)

    lons, lats = sample_data()

    # to get the effect of having just the states without a map "background"
    # turn off the outline and background patches
    ax.background_patch.set_visible(False)
    ax.outline_patch.set_visible(False)

    plt.title('US States which intersect the track '
              'of Hurricane Katrina (2005)')

    # turn the lons and lats into a shapely LineString
    track = sgeom.LineString(zip(lons, lats))

    # buffer the linestring by two degrees (note: this is a non-physical
    # distance)
    track_buffer = track.buffer(2)

    for state in shpreader.Reader(states_shp).geometries():
        # pick a default color for the land with a black outline,
        # this will change if the storm intersects with our track
        facecolor = [0.9375, 0.9375, 0.859375]
        edgecolor = 'black'

        if state.intersects(track):
            facecolor = 'red'
        elif state.intersects(track_buffer):
            facecolor = '#FF7E00'

        ax.add_geometries([state], ccrs.PlateCarree(),
                          facecolor=facecolor, edgecolor=edgecolor)

    ax.add_geometries([track_buffer], ccrs.PlateCarree(),
                      facecolor='#C8A2C8', alpha=0.5)
    ax.add_geometries([track], ccrs.PlateCarree(),
                      facecolor='none',  edgecolor='green')

    # make two proxy artists to add to a legend
    direct_hit = mpatches.Rectangle((0, 0), 1, 1, facecolor="red")
    within_2_deg = mpatches.Rectangle((0, 0), 1, 1, facecolor="#FF7E00")
    labels = ['State directly intersects\nwith track',
              'State is within \n2 degrees of track']
    plt.legend([direct_hit, within_2_deg], labels,
               loc='lower left', bbox_to_anchor=(0.025, -0.1), fancybox=True)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_23_0.png)

### image_tiles example

```python
"""
Web tile imagery
----------------

This example demonstrates how imagery from a tile
providing web service can be accessed.

"""
import matplotlib.pyplot as plt

from cartopy.io.img_tiles import StamenTerrain

def main():
    tiler = StamenTerrain()
    mercator = tiler.crs
    fig = plt.figure(figsize=(8,8))
    ax = plt.axes(projection=mercator)
    ax.set_extent([-90, -73, 22, 34])

    ax.add_image(tiler, 6)

    ax.coastlines('10m')
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_25_0.png)

### logo example

```python
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.textpath
import matplotlib.patches
from matplotlib.font_manager import FontProperties
import numpy as np

def main():
    plt.figure(figsize=[12, 6])
    ax = plt.axes(projection=ccrs.Robinson())

    ax.coastlines()
    ax.gridlines()

    # generate a matplotlib path representing the word "cartopy"
    fp = FontProperties(family='Bitstream Vera Sans', weight='bold')
    logo_path = matplotlib.textpath.TextPath((-175, -35), 'cartopy',
                                             size=1, prop=fp)
    # scale the letters up to sensible longitude and latitude sizes
    logo_path._vertices *= np.array([80, 160])

    # add a background image
    im = ax.stock_img()
    # clip the image according to the logo_path. mpl v1.2.0 does not support
    # the transform API that cartopy makes use of, so we have to convert the
    # projection into a transform manually
    plate_carree_transform = ccrs.PlateCarree()._as_mpl_transform(ax)
    im.set_clip_path(logo_path, transform=plate_carree_transform)

    # add the path as a patch, drawing black outlines around the text
    patch = matplotlib.patches.PathPatch(logo_path,
                                         facecolor='none', edgecolor='black',
                                         transform=ccrs.PlateCarree())
    ax.add_patch(patch)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_27_0.png)

### Regridding vectors with quiver

```python
"""
Regridding vectors with quiver
------------------------------

This example demonstrates the regridding functionality in quiver (there exists
equivalent functionality in :meth:`cartopy.mpl.geoaxes.GeoAxes.barbs`).

Regridding can be an effective way of visualising a vector field, particularly
if the data is dense or warped.
"""
import matplotlib.pyplot as plt
import numpy as np

import cartopy.crs as ccrs

def sample_data(shape=(20, 30)):
    """
    Returns ``(x, y, u, v, crs)`` of some vector data
    computed mathematically. The returned CRS will be a North Polar
    Stereographic projection, meaning that the vectors will be unevenly
    spaced in a PlateCarree projection.

    """
    crs = ccrs.NorthPolarStereo()
    scale = 1e7
    x = np.linspace(-scale, scale, shape[1])
    y = np.linspace(-scale, scale, shape[0])

    x2d, y2d = np.meshgrid(x, y)
    u = 10 * np.cos(2 * x2d / scale + 3 * y2d / scale)
    v = 20 * np.cos(6 * x2d / scale)

    return x, y, u, v, crs

def main():
    plt.figure(figsize=(8, 10))

    x, y, u, v, vector_crs = sample_data(shape=(50, 50))
    ax1 = plt.subplot(2, 1, 1, projection=ccrs.PlateCarree())
    ax1.coastlines('50m')
    ax1.set_extent([-45, 55, 20, 80], ccrs.PlateCarree())
    ax1.quiver(x, y, u, v, transform=vector_crs)

    ax2 = plt.subplot(2, 1, 2, projection=ccrs.PlateCarree())
    plt.title('The same vector field regridded')
    ax2.coastlines('50m')
    ax2.set_extent([-45, 55, 20, 80], ccrs.PlateCarree())
    ax2.quiver(x, y, u, v, transform=vector_crs, regrid_shape=20)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_29_0.png)

### reprojected_wmts example

```python
"""
Displaying WMTS tiled map data on an arbitrary projection
---------------------------------------------------------

This example displays imagery from a web map tile service on two different
projections, one of which is not provided by the service.

This result can also be interactively panned and zoomed.

The example WMTS layer is a single composite of data sampled over nine days
in April 2012 and thirteen days in October 2012 showing the Earth at night.
It does not vary over time.

The imagery was collected by the Suomi National Polar-orbiting Partnership
(Suomi NPP) weather satellite operated by the United States National Oceanic
and Atmospheric Administration (NOAA).

"""

import matplotlib.pyplot as plt
import cartopy.crs as ccrs

def plot_city_lights():
    # Define resource for the NASA night-time illumination data.
    base_uri = 'http://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi'
    layer_name = 'VIIRS_CityLights_2012'

    # Create a Cartopy crs for plain and rotated lat-lon projections.
    plain_crs = ccrs.PlateCarree()
    rotated_crs = ccrs.RotatedPole(pole_longitude=120.0, pole_latitude=45.0)

    # Plot WMTS data in a specific region, over a plain lat-lon map.
    ax = plt.subplot(121, projection=plain_crs)
    ax.set_extent((-6, 3, 48, 58), crs=ccrs.PlateCarree())
    ax.coastlines(resolution='50m', color='yellow')
    ax.gridlines(color='lightgrey', linestyle='-')
    # Add WMTS imaging.
    ax.add_wmts(base_uri, layer_name=layer_name)

    # Plot WMTS data on a rotated map, over the same nominal region.
    ax = plt.subplot(122, projection=rotated_crs)
    ax.set_extent((-6, 3, 48, 58), crs=plain_crs)
    ax.coastlines(resolution='50m', color='yellow')
    ax.gridlines(color='lightgrey', linestyle='-')
    # Add WMTS imaging.
    ax.add_wmts(base_uri, layer_name=layer_name)

    plt.show()

if __name__ == '__main__':
    plot_city_lights()
```

![png](/images/cartopygallery/output_31_0.png)

### Rotated pole boxes

This example demonstrates the way a box is warped when it is defined in a rotated pole coordinate system.

Try changing the box_top to 44, 46 and 75 to see the effect that including the pole in the polygon has.

```python
"""
Rotated pole boxes
------------------

This example demonstrates the way a box is warped when it is defined
in a rotated pole coordinate system.

Try changing the ``box_top`` to ``44``, ``46`` and ``75`` to see the effect
that including the pole in the polygon has.

"""

import matplotlib.pyplot as plt

import cartopy.crs as ccrs

def main():
    fig = plt.figure(figsize=(8,15))
    rotated_pole = ccrs.RotatedPole(pole_latitude=45, pole_longitude=180)

    box_top = 45
    x, y = [-44, -44, 45, 45, -44], [-45, box_top, box_top, -45, -45]

    ax = plt.subplot(211, projection=rotated_pole)
    ax.stock_img()
    ax.coastlines()
    ax.plot(x, y, marker='o', transform=rotated_pole)
    ax.fill(x, y, color='coral', transform=rotated_pole, alpha=0.4)
    ax.gridlines()

    ax = plt.subplot(212, projection=ccrs.PlateCarree())
    ax.stock_img()
    ax.coastlines()
    ax.plot(x, y, marker='o', transform=rotated_pole)
    ax.fill(x, y, transform=rotated_pole, color='coral', alpha=0.4)
    ax.gridlines()

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_33_0.png)

### Modifying the boundary/neatline of a map in cartopy

This example demonstrates how to modify the boundary/neatline of an axes. We construct a star with coordinates in a Plate Carree coordinate system, and use the star as the outline of the map.

Notice how changing the projection of the map represents a projected star shaped boundary.

```python
"""
Modifying the boundary/neatline of a map in cartopy
---------------------------------------------------

This example demonstrates how to modify the boundary/neatline
of an axes. We construct a star with coordinates in a Plate Carree
coordinate system, and use the star as the outline of the map.

Notice how changing the projection of the map represents a *projected*
star shaped boundary.

"""
import matplotlib.path as mpath
import matplotlib.pyplot as plt

import cartopy.crs as ccrs

def main():
    ax = plt.axes([0, 0, 1, 1], projection=ccrs.PlateCarree())
    ax.coastlines()

    # Construct a star in longitudes and latitudes.
    star_path = mpath.Path.unit_regular_star(5, 0.5)
    star_path = mpath.Path(star_path.vertices.copy() * 80,
                           star_path.codes.copy())

    # Use the star as the boundary.
    ax.set_boundary(star_path, transform=ccrs.PlateCarree())

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_35_0.png)

### streamplot example

```python
import matplotlib.pyplot as plt

import cartopy.crs as ccrs
from cartopy.examples.arrows import sample_data

def main():
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([-90, 75, 10, 60])
    ax.coastlines()

    x, y, u, v, vector_crs = sample_data(shape=(80, 100))
    magnitude = (u ** 2 + v ** 2) ** 0.5
    ax.streamplot(x, y, u, v, transform=vector_crs,
                  linewidth=2, density=2, color=magnitude)
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_37_0.png)

### tick_labels example

```python
"""
This example demonstrates adding tick labels to maps on rectangular
projections using special tick formatters.

"""
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import matplotlib.pyplot as plt

def main():
    plt.figure(figsize=(8, 10))

    # Label axes of a Plate Carree projection with a central longitude of 180:
    ax1 = plt.subplot(211, projection=ccrs.PlateCarree(central_longitude=180))
    ax1.set_global()
    ax1.coastlines()
    ax1.set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
    ax1.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
    lon_formatter = LongitudeFormatter(zero_direction_label=True)
    lat_formatter = LatitudeFormatter()
    ax1.xaxis.set_major_formatter(lon_formatter)
    ax1.yaxis.set_major_formatter(lat_formatter)

    # Label axes of a Mercator projection without degree symbols in the labels
    # and formatting labels to include 1 decimal place:
    ax2 = plt.subplot(212, projection=ccrs.Mercator())
    ax2.set_global()
    ax2.coastlines()
    ax2.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
    ax2.set_yticks([-78.5, -60, -25.5, 25.5, 60, 80], crs=ccrs.PlateCarree())
    lon_formatter = LongitudeFormatter(number_format='.1f',
                                       degree_symbol='',
                                       dateline_direction_label=True)
    lat_formatter = LatitudeFormatter(number_format='.1f',
                                      degree_symbol='')
    ax2.xaxis.set_major_formatter(lon_formatter)
    ax2.yaxis.set_major_formatter(lat_formatter)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_39_0.png)

### tissot example

```python
import matplotlib.pyplot as plt

import cartopy.crs as ccrs

def main():
    plt.figure(figsize=(10, 20))
    ax = plt.axes(projection=ccrs.PlateCarree())

    # make the map global rather than have it zoom in to
    # the extents of any plotted data
    ax.set_global()

    ax.stock_img()
    ax.coastlines()

    ax.tissot(facecolor='orange', alpha=0.4)

    plt.show()

if __name__ == '__main__':
    main()
```

    /home/ding/anaconda3/lib/python3.6/site-packages/cartopy/mpl/geoaxes.py:598: UserWarning: Approximating coordinate system <cartopy._crs.Geodetic object at 0x7f9be39500f8> with the PlateCarree projection.
      'PlateCarree projection.'.format(crs))

![png](/images/cartopygallery/output_41_1.png)

### tube_stations example

```python
"""
Produces a map showing London Underground station locations with high
resolution background imagery provided by OpenStreetMap.

"""
from matplotlib.path import Path
import matplotlib.pyplot as plt
import numpy as np

import cartopy.crs as ccrs
from cartopy.io.img_tiles import OSM

def tube_locations():
    """
    Returns an (n, 2) array of selected London Tube locations in Ordnance
    Survey GB coordinates.

    Source: http://www.doogal.co.uk/london_stations.php

    """
    return np.array([[531738., 180890.], [532379., 179734.],
                     [531096., 181642.], [530234., 180492.],
                     [531688., 181150.], [530242., 180982.],
                     [531940., 179144.], [530406., 180380.],
                     [529012., 180283.], [530553., 181488.],
                     [531165., 179489.], [529987., 180812.],
                     [532347., 180962.], [529102., 181227.],
                     [529612., 180625.], [531566., 180025.],
                     [529629., 179503.], [532105., 181261.],
                     [530995., 180810.], [529774., 181354.],
                     [528941., 179131.], [531050., 179933.],
                     [530240., 179718.]])

def main():
    imagery = OSM()
    plt.figure(figsize=(8, 10))
    ax = plt.axes(projection=imagery.crs)
    ax.set_extent((-0.14, -0.1, 51.495, 51.515))

    # Construct concentric circles and a rectangle,
    # suitable for a London Underground logo.
    theta = np.linspace(0, 2 * np.pi, 100)
    circle_verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    concentric_circle = Path.make_compound_path(Path(circle_verts[::-1]),
                                                Path(circle_verts * 0.6))

    rectangle = Path([[-1.1, -0.2], [1, -0.2], [1, 0.3], [-1.1, 0.3]])

    # Add the imagery to the map.
    ax.add_image(imagery, 14)

    # Plot the locations twice, first with the red concentric circles,
    # then with the blue rectangle.
    xs, ys = tube_locations().T
    plt.plot(xs, ys, transform=ccrs.OSGB(),
             marker=concentric_circle, color='green', markersize=9,
             linestyle='')
    plt.plot(xs, ys, transform=ccrs.OSGB(),
             marker=rectangle, color='yellow', markersize=11,
             linestyle='')

    plt.title('London underground locations')
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_43_0.png)

### un_flag example

```python
import cartopy.crs as ccrs
import cartopy.feature
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
import matplotlib.path
import matplotlib.ticker
from matplotlib.transforms import BboxTransform, Bbox
import numpy as np

# When drawing the flag, we can either use white filled land, or be a little
# more fancy and use the Natural Earth shaded relief imagery.
filled_land = True

def olive_path():
    """
    Returns a matplotlib path representing a single olive branch from the
    UN Flag. The path coordinates were extracted from the SVG at
    https://commons.wikimedia.org/wiki/File:Flag_of_the_United_Nations.svg.

    """
    olives_verts = np.array(
        [[0,   2,   6,   9,  30,  55,  79,  94, 104, 117, 134, 157, 177,
          188, 199, 207, 191, 167, 149, 129, 109,  87,  53,  22,   0, 663,
          245, 223, 187, 158, 154, 150, 146, 149, 154, 158, 181, 184, 197,
          181, 167, 153, 142, 129, 116, 119, 123, 127, 151, 178, 203, 220,
          237, 245, 663, 280, 267, 232, 209, 205, 201, 196, 196, 201, 207,
          211, 224, 219, 230, 220, 212, 207, 198, 195, 176, 197, 220, 239,
          259, 277, 280, 663, 295, 293, 264, 250, 247, 244, 240, 240, 243,
          244, 249, 251, 250, 248, 242, 245, 233, 236, 230, 228, 224, 222,
          234, 249, 262, 275, 285, 291, 295, 296, 295, 663, 294, 293, 292,
          289, 294, 277, 271, 269, 268, 265, 264, 264, 264, 272, 260, 248,
          245, 243, 242, 240, 243, 245, 247, 252, 256, 259, 258, 257, 258,
          267, 285, 290, 294, 297, 294, 663, 285, 285, 277, 266, 265, 265,
          265, 277, 266, 268, 269, 269, 269, 268, 268, 267, 267, 264, 248,
          235, 232, 229, 228, 229, 232, 236, 246, 266, 269, 271, 285, 285,
          663, 252, 245, 238, 230, 246, 245, 250, 252, 255, 256, 256, 253,
          249, 242, 231, 214, 208, 208, 227, 244, 252, 258, 262, 262, 261,
          262, 264, 265, 252, 663, 185, 197, 206, 215, 223, 233, 242, 237,
          237, 230, 220, 202, 185, 663],
         [8,   5,   3,   0,  22,  46,  46,  46,  35,  27,  16,  10,  18,
          22,  28,  38,  27,  26,  33,  41,  52,  52,  52,  30,   8, 595,
          77,  52,  61,  54,  53,  52,  53,  55,  55,  57,  65,  90, 106,
          96,  81,  68,  58,  54,  51,  50,  51,  50,  44,  34,  43,  48,
          61,  77, 595, 135, 104, 102,  83,  79,  76,  74,  74,  79,  84,
          90, 109, 135, 156, 145, 133, 121, 100,  77,  62,  69,  67,  80,
          92, 113, 135, 595, 198, 171, 156, 134, 129, 124, 120, 123, 126,
          129, 138, 149, 161, 175, 188, 202, 177, 144, 116, 110, 105,  99,
          108, 116, 126, 136, 147, 162, 173, 186, 198, 595, 249, 255, 261,
          267, 241, 222, 200, 192, 183, 175, 175, 175, 175, 199, 221, 240,
          245, 250, 256, 245, 233, 222, 207, 194, 180, 172, 162, 153, 154,
          171, 184, 202, 216, 233, 249, 595, 276, 296, 312, 327, 327, 327,
          327, 308, 284, 262, 240, 240, 239, 239, 242, 244, 247, 265, 277,
          290, 293, 296, 300, 291, 282, 274, 253, 236, 213, 235, 252, 276,
          595, 342, 349, 355, 357, 346, 326, 309, 303, 297, 291, 290, 297,
          304, 310, 321, 327, 343, 321, 305, 292, 286, 278, 270, 276, 281,
          287, 306, 328, 342, 595, 379, 369, 355, 343, 333, 326, 318, 328,
          340, 349, 366, 373, 379, 595]]).T
    olives_codes = np.array([1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 4, 4, 4, 4, 79, 1, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 4, 79, 1, 4, 4, 4, 4, 4, 4, 2, 4,
                             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 79, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 79, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
                             4, 4, 4, 4, 4, 79, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 4, 4, 79, 1, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 4, 4, 79, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             4, 4, 79], dtype=np.uint8)

    return matplotlib.path.Path(olives_verts, olives_codes)

def main():
    blue = '#4b92db'

    # We're drawing a flag with a 3:5 aspect ratio.
    fig = plt.figure(figsize=[10, 6], facecolor=blue)
    # Put a blue background on the figure.
    blue_background = PathPatch(matplotlib.path.Path.unit_rectangle(),
                                transform=fig.transFigure, color=blue,
                                zorder=-1)
    fig.patches.append(blue_background)

    # Set up the Azimuthal Equidistant and Plate Carree projections
    # for later use.
    az_eq = ccrs.AzimuthalEquidistant(central_latitude=90)
    pc = ccrs.PlateCarree()

    # Pick a suitable location for the map (which is in an Azimuthal
    # Equidistant projection).
    ax = plt.axes([0.25, 0.24, 0.5, 0.54], projection=az_eq)

    # The background patch and outline patch are not needed in this example.
    ax.background_patch.set_facecolor('none')
    ax.outline_patch.set_edgecolor('none')

    # We want the map to go down to -60 degrees latitude.
    ax.set_extent([-180, 180, -60, 90], ccrs.PlateCarree())

    # Importantly, we want the axes to be circular at the -60 latitude
    # rather than cartopy's default behaviour of zooming in and becoming
    # square.
    _, patch_radius = az_eq.transform_point(0, -60, pc)
    circular_path = matplotlib.path.Path.circle(0, patch_radius)
    ax.set_boundary(circular_path)

    if filled_land:
        ax.add_feature(
            cartopy.feature.LAND, facecolor='white', edgecolor='none')
    else:
        ax.stock_img()

    gl = ax.gridlines(crs=pc, linewidth=3, color='white', linestyle='-')
    # Meridians every 45 degrees, and 5 parallels.
    gl.xlocator = matplotlib.ticker.FixedLocator(np.arange(0, 361, 45))
    parallels = np.linspace(-60, 70, 5, endpoint=True)
    gl.ylocator = matplotlib.ticker.FixedLocator(parallels)

    # Now add the olive branches around the axes. We do this in normalised
    # figure coordinates
    olive_leaf = olive_path()

    olives_bbox = Bbox.null()
    olives_bbox.update_from_path(olive_leaf)

    # The first olive branch goes from left to right.
    olive1_axes_bbox = Bbox([[0.45, 0.15], [0.725, 0.75]])
    olive1_trans = BboxTransform(olives_bbox, olive1_axes_bbox)

    # THe second olive branch goes from right to left (mirroring the first).
    olive2_axes_bbox = Bbox([[0.55, 0.15], [0.275, 0.75]])
    olive2_trans = BboxTransform(olives_bbox, olive2_axes_bbox)

    olive1 = PathPatch(olive_leaf, facecolor='white', edgecolor='none',
                       transform=olive1_trans + fig.transFigure)
    olive2 = PathPatch(olive_leaf, facecolor='white', edgecolor='none',
                       transform=olive2_trans + fig.transFigure)

    fig.patches.append(olive1)
    fig.patches.append(olive2)

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_45_0.png)

### waves example

```python
import matplotlib.pyplot as plt
import numpy as np

import cartopy.crs as ccrs

def sample_data(shape=(73, 145)):
    """Returns ``lons``, ``lats`` and ``data`` of some fake data."""
    nlats, nlons = shape
    lats = np.linspace(-np.pi / 2, np.pi / 2, nlats)
    lons = np.linspace(0, 2 * np.pi, nlons)
    lons, lats = np.meshgrid(lons, lats)
    wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons)
    mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2)

    lats = np.rad2deg(lats)
    lons = np.rad2deg(lons)
    data = wave + mean

    return lons, lats, data

def main():
    ax = plt.axes(projection=ccrs.Mollweide())

    lons, lats, data = sample_data()

    ax.contourf(lons, lats, data,
                transform=ccrs.PlateCarree(),
                cmap='spectral')
    ax.coastlines()
    ax.set_global()
    plt.show()

if __name__ == '__main__':
    main()
```

    /home/ding/anaconda3/lib/python3.6/site-packages/matplotlib/cbook.py:136: MatplotlibDeprecationWarning: The spectral and spectral_r colormap was deprecated in version 2.0. Use nipy_spectral and nipy_spectral_r instead.
      warnings.warn(message, mplDeprecation, stacklevel=1)

![png](/images/cartopygallery/output_47_1.png)

### wms example

```python
"""
Interactive WMS (Web Map Service)
---------------------------------

This example demonstrates the interactive pan and zoom capability
supported by an OGC web services Web Map Service (WMS) aware axes.

"""
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

def main():
    ax = plt.axes(projection=ccrs.InterruptedGoodeHomolosine())
    ax.coastlines()

    ax.add_wms(wms='http://vmap0.tiles.osgeo.org/wms/vmap0',
               layers=['basic'])

    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_49_0.png)

### wmts example

```python
"""
Interactive WMTS (Web Map Tile Service)
---------------------------------------

This example demonstrates the interactive pan and zoom capability
supported by an OGC web services Web Map Tile Service (WMTS) aware axes.

The example WMTS layer is a single composite of data sampled over nine days
in April 2012 and thirteen days in October 2012 showing the Earth at night.
It does not vary over time.

The imagery was collected by the Suomi National Polar-orbiting Partnership
(Suomi NPP) weather satellite operated by the United States National Oceanic
and Atmospheric Administration (NOAA).

"""

import cartopy.crs as ccrs
import matplotlib.pyplot as plt

def main():
    url = 'https://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi'
    layer = 'VIIRS_CityLights_2012'

    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.add_wmts(url, layer)
    ax.set_extent((-15, 25, 35, 60))

    plt.title('Suomi NPP Earth at night April/October 2012')
    plt.show()

if __name__ == '__main__':
    main()
```

![png](/images/cartopygallery/output_51_0.png)

### wmts_time example

```python
"""
Web Map Tile Service time dimension demonstration
-------------------------------------------------

This example further demonstrates WMTS support within cartopy. Optional
keyword arguments can be supplied to the OGC WMTS 'gettile' method. This
allows for the specification of the 'time' dimension for a WMTS layer
which supports it.

The example shows satellite imagery retrieved from NASA's Global Imagery
Browse Services for 5th Feb 2016. A true color MODIS image is shown on
the left, with the MODIS false color 'snow RGB' shown on the right.

"""
import matplotlib.pyplot as plt
import matplotlib.patheffects as PathEffects
import cartopy.crs as ccrs
from owslib.wmts import WebMapTileService

def main():
    # URL of NASA GIBS
    URL = 'https://gist.github.com/pelson/5871263/raw/'
           'EIDA50_201211061300_clip2.png'
    wmts = WebMapTileService(URL)

    # Layers for MODIS true color and snow RGB
    layers = ['MODIS_Terra_SurfaceReflectance_Bands143',
              'MODIS_Terra_CorrectedReflectance_Bands367']

    date_str = '2016-02-05'

    # Plot setup
    plot_CRS = ccrs.Mercator()
    geodetic_CRS = ccrs.Geodetic()
    x0, y0 = plot_CRS.transform_point(4.6, 43.1, geodetic_CRS)
    x1, y1 = plot_CRS.transform_point(11.0, 47.4, geodetic_CRS)
    ysize = 8
    xsize = 2 * ysize * (x1 - x0) / (y1 - y0)
    fig = plt.figure(figsize=(xsize, ysize), dpi=100)

    for layer, offset in zip(layers, [0, 0.5]):
        ax = plt.axes([offset, 0, 0.5, 1], projection=plot_CRS)
        ax.set_xlim((x0, x1))
        ax.set_ylim((y0, y1))
        ax.add_wmts(wmts, layer, wmts_kwargs={'time': date_str})
        txt = plt.text(4.7, 43.2, wmts[layer].title, fontsize=18,
                       color='wheat', transform=geodetic_CRS)
        txt.set_path_effects([PathEffects.withStroke(linewidth=5,
                                                     foreground='black')])
    plt.show()

if __name__ == '__main__':
    main()
```

    IOPub data rate exceeded.
    The notebook server will temporarily stop sending /images/cartopygallery/output
    to the client in order to avoid crashing it.
    To change this limit, set the config variable
    `--NotebookApp.iopub_data_rate_limit`.

```python

```


text:
---
title: "Ffmpeg Gists"
date: 2014-06-9
template: "post.hbs"
---

## ffmpeg: Convert mov to mp4

Convert from **mov** to **mp4**:

`ffmpeg -i movie.mov -vcodec copy -acodec copy output.mp4`

To do compression:

`ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4`

>Calculate the bitrate you need by dividing 1 GB by the video length in seconds. So, for a video of length 16:40 (1000 seconds), use a bitrate of 1000000 bytes/sec:

>ffmpeg -i input.mp4 -b 1000000 output.mp4
Additional options that might be worth considering is setting the Constant Rate Factor, which lowers the average bit rate, but retains better quality. Vary the CRF between around 18 and 24 — the lower, the higher the bitrate.

>ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4

## prores
`ffmpeg -i placeholder.mov -vcodec libx264 -acodec libfaac -b:v 1000k -b:a 128k -threads 0 -pix_fmt yuv420p orientation_raw.mp4`

license: MIT

branch_name: HEAD

extension: md

license_type: permissive


text:
## Seed segmentation

Skoltech project that aims to perform image segmentation to detect seeds and measure root lengths from the images. The project is developed by Skoltech student (reference not available) and is not finished.

path: /Seed segmentation/README.md

branch_name: refs/heads/master


text:
---
title: TiDB Cloud Quick Start
summary: Sign up quickly to try TiDB Cloud and create your TiDB cluster.
category: quick start
aliases: ['/tidbcloud/beta/tidb-cloud-quickstart']
---

# TiDB Cloud Quick Start

*Estimated completion time: 20 minutes*

This tutorial guides you through an easy way to get started with your TiDB Cloud. The content includes how to create a cluster, connect to a cluster, import data, and run queries.

## Step 1. Create a TiDB cluster

You can either create a free [Developer Tier](/tidb-cloud/select-cluster-tier.md#developer-tier) cluster or a [Dedicated Tier](/tidb-cloud/select-cluster-tier.md#dedicated-tier).

<SimpleTab>

To create a free Developer Tier cluster, take the following steps:

1. If you do not have a TiDB Cloud account, click [here](https://tidbcloud.com/free-trial) to sign up for an account.

    - For Google users, you can also sign up with Google. To do that, click **Sign up with Google** on the [sign up](https://tidbcloud.com/signup) page. Your email address and password will be managed by Google and cannot be changed using TiDB Cloud console.
    - For GitHub users, you can also sign up with GitHub. To do that, click **Sign up with GitHub** on the [sign up](https://tidbcloud.com/signup) page. Your email address and password will be managed by GitHub and cannot be changed using TiDB Cloud console.

2. [Log in](https://tidbcloud.com/) to your TiDB Cloud account.

    The plan selection page is displayed by default.

3. On the plan selection page, click **Get Started for Free** in the **Developer Tier** plan.

4. On the **Create a Cluster (Developer Tier)** page, update the default cluster name if necessary, and then select the region where you want to create your cluster.

5. Click **Create**.

   The cluster creation process starts and the **Security Quick Start** dialog box is displayed.

6. In the **Security Quick Start** dialog box, set the root password and allowed IP addresses to connect to your cluster, and then click **Apply**.

    Your TiDB Cloud cluster will be created in approximately 5 to 15 minutes.

To create a Dedicated Tier cluster, take the following steps:

1. If you do not have a TiDB Cloud account, click [here](https://tidbcloud.com/signup) to sign up for an account.

    - For Google users, you can also sign up with Google. To do that, click **Sign up with Google** on the [sign up](https://tidbcloud.com/signup) page. Your email address and password will be managed by Google and cannot be changed using TiDB Cloud console.
    - For GitHub users, you can also sign up with GitHub. To do that, click **Sign up with GitHub** on the [sign up](https://tidbcloud.com/signup) page. Your email address and password will be managed by GitHub and cannot be changed using TiDB Cloud console.
    - For AWS Marketplace users, you can also sign up through AWS Marketplace. To do that, search for `TiDB Cloud` in [AWS Marketplace](https://aws.amazon.com/marketplace), subscribe to TiDB Cloud, and then follow the onscreen instructions to set up your TiDB Cloud account.

2. [Log in](https://tidbcloud.com/) to your TiDB Cloud account.

    The plan selection page is displayed by default.

3. On the plan selection page, click **Get Full Access Today** in the **Dedicated Tier** plan.

    > **Note:**
    >
    > If you want to get a 14-day free trial of TiDB Cloud Dedicated Tier first, see [Perform a Proof of Concept (PoC) with TiDB Cloud](/tidb-cloud/tidb-cloud-poc.md).

4. On the **Create a Cluster** page, update the default cluster name and port number if necessary, choose a cloud provider and a region, and then click **Next**.

5. If this is the first cluster of your current project and CIDR has not been configured for this project, you need to set the project CIDR, and then click **Next**. If you do not see the **project CIDR** field, it means that CIDR has already been configured for this project.

    > **Note:**
    >
    > When setting the project CIDR, avoid any conflicts with the CIDR of the VPC where your application is located. The CIDR of a project cannot be modified once it is set.

6. Configure the [cluster size](/tidb-cloud/size-your-cluster.md) for TiDB, TiKV, and TiFlash (optional) respectively, and then click **Next**.

7. Confirm the cluster information in the middle area and also the billing information in the right pane.

8. Click **Add Credit Card** in the right pane to add a credit card for your account.

9. Click **Create**.

   The cluster creation process starts and the **Security Quick Start** dialog box is displayed.

10. In the **Security Quick Start** dialog box, set the root password and allowed IP addresses to connect to your cluster, and then click **Apply**.

    Your TiDB Cloud cluster will be created in approximately 5 to 15 minutes.

</SimpleTab>

## Step 2. Connect to your TiDB cluster

1. On the **Active Clusters** page, click the name of your newly created cluster.

    The overview page of your newly created cluster is displayed.

2. Click **Connect**. The **Connect to TiDB** dialog box is displayed.

3. Under **Step 2: Connect with a SQL client** in the dialog box, click the tab of your preferred connection method, and then connect to your cluster with the connection string.

    > **Note:**
    >
    > - For [Developer Tier clusters](/tidb-cloud/select-cluster-tier.md#developer-tier), when you connect to your cluster, you must include the prefix for your cluster in the user name and wrap the name with quotation marks. For more information, see [User name prefix](/tidb-cloud/select-cluster-tier.md#user-name-prefix).
    > - TiDB Cloud is MySQL-compatible, so you can connect to your cluster using any MySQL client tools. We recommend using [mysql — The MySQL Command-Line Client](https://dev.mysql.com/doc/refman/8.0/en/mysql.html) or [mysql — The MySQL Command-Line Client from MariaDB](https://mariadb.com/kb/en/mysql-command-line-client/).

4. After logging into your TiDB cluster, you can use the following SQL statement to validate the connection:

    {{< copyable "sql" >}}

    ```sql
    SELECT TiDB_version();
    ```

    If you see the release version information, you are ready to use your TiDB cluster.

## Step 3. Import the sample data

We provide Capital Bikeshare sample data for you to easily import data and run sample queries.

1. Navigate to the **Active Clusters** page and click the name of your newly created cluster. The overview page of your cluster is displayed.

2. In the cluster information pane on the left, click **Import**. The **Data Import Task** page is displayed.

3. Fill in the import parameters:

    <SimpleTab>

    If your TiDB cluster is hosted by AWS (the Developer Tier is hosted by AWS by default), fill in the following parameters:

    - **Data Source Type**: `AWS S3`.
    - **Bucket URL**: enter the sample data URL `s3://tidbcloud-samples/data-ingestion/`.
    - **Data Format**: select **TiDB Dumpling**.
    - **Setup Credentials**: enter `arn:aws:iam::385595570414:role/import-sample-access` for Role-ARN.
    - **Target Database**:
        - **Username**: `root`.
        - **Password**: enter your root password.
    - **DB/Tables Filter**: leave this field blank.

    If your TiDB cluster is hosted by GCP, fill in the following parameters:

    - **Data Source Type**: `Google Cloud Stroage`.
    - **Bucket URL**: enter the sample data URL `gcs://tidbcloud-samples-us-west1`.
    - **Data Format**: select **TiDB Dumpling**.
    - **Target Database**:
        - **Username**: `root`.
        - **Password**: enter your root password.
    - **DB/Tables Filter**: leave this field blank.

    </SimpleTab>

4. Click **Import**.

    A warning message about the database resource consumption is displayed. For a newly created cluster, you can ignore the warning message.

5. Click **Confirm**.

    TiDB Cloud starts validating whether it can access the sample data in the specified bucket URL. After the validation is completed and successful, the import task starts automatically.

The data import process will take 5 to 10 minutes. When the data import progress bar shows **Success**, you successfully import the sample data and the database schema in your database.

## Step 4. Query data

When the process of importing data is completed, you can start to run some queries in your Terminal:

1. Use the `bikeshare` database and tables:

    {{< copyable "sql" >}}

    ```sql
    USE bikeshare;
    SHOW tables;
    ```

2. Check the structure of the `trip` table:

    {{< copyable "sql" >}}

    ```sql
    DESCRIBE trips;
    ```

3. Check how many records exist in the `trips` table:

    {{< copyable "sql" >}}

    ```sql
    SELECT COUNT(*) FROM trips;
    ```

4. Check the entire trip history where the start station is "8th & D St NW":

    {{< copyable "sql" >}}

    ```sql
    SELECT * FROM trips WHERE start_station_name = '8th & D St NW';
    ```

5. Show the least ten popular bicycle stations for picking up:

    {{< copyable "sql" >}}

    ```sql
    SELECT start_station_name, COUNT(ride_id) as count from `trips`
    GROUP BY start_station_name
    ORDER BY count ASC
    LIMIT 10;
    ```

repository: JaySon-Huang/docs

repo_name: JaySon-Huang/docs


text:
# Build fleet-ui docker image

Feature: No need to install required packages on a host in order to build fleetui image. This tool builds a 'builder' image and uses it to build [purpleworks/fleet-ui](https://github.com/purpleworks/fleet-ui.git).

## Quick start

Take a look at the build.sh if you need to change the default fleetctl version or fleet-ui.git repo. Then:

	./build.sh

  It builds two images. The first one is _fleet-ui-builder_, and then the script calls it to build _fleet-ui_, which is the image you will run as a service.

  You can customize the default fleet-ui repo or fleetctl version in the build.sh.

## Use ready-make docker-fleet-ui builder image
```
docker pull xuwang/docker-fleetui-builder
```

Replace the FLEETUIREPO with your fleet-ui repo or use the default [purpleworks/fleet-ui](https://github.com/purpleworks/fleet-ui.git)
```
$ docker run -t --rm \
	-v /var/run/docker.sock:/var/run/docker.sock \
	--env FLEET_VERSION=v0.11.8 \
	--env FLEETUIREPO=github.com/purpleworks/fleet-ui \
	--dns <IP_ADDRESS> \
	xuwang/docker-fleetui-builder
```

The output:

```
+ docker run -t --rm -v /var/run/docker.sock:/var/run/docker.sock --env FLEETUIREPO=github.com/xueshanf/fleet-ui --dns <IP_ADDRESS> xuwang/docker-fleetui-builder
FLEET-UI REPO - github.com/purpleworks/fleet-ui
FLEET VERSION - v0.11.5
BUILD DOCKER IMAGE VERSION - latest
...
```

## Run the fleet-ui on CoreOS

Here is an example of how to [Run fleet-ui on CoreOS.](https://github.com/xuwang/coreos-docker-dev/blob/master/README-fleet-ui.md)

## How does it work

The builder Dockerfile creates an isolated docker enviromment, with the required software packages and docker daemon installed. The result
image is called _fleet-ui-builder_ which, when run, will build _fleet-ui_ docker image. _fleet-ui_ image is the one you will run or push to your dockerhub account to share.

The builder environment includes:

* latest golang
* npm, ruby, gem etc.
* docker from Debian/Jessie release

The builder image can be removed when you are sure you have a good fleet-ui image:

	docker rmi fleet-ui-builder:latest

## Troubleshoot

If you have problem with the fleet-ui, you can debug your build environment by run the builder image:

	docker run --rm -i -t fleet-ui-builder bash

The fleet-ui source code downloaded by Go is located at /gopath directory:

![fleet-ui src tree](https://github.com/xuwang/docker-fleetui-builder/blob/master/images/fleet-ui-src.png "fleet-ui src tree")

Then you can manually run steps in the builder Dockerfile for troubleshooting issues.


text:
---
title: 'From the developer'
---

Hi! I am [Kushagra Gour](https://twitter.com/chinchang457), a frontend developer from India. I created Web Maker as a side project from myself because I wanted a frontend playground that was fast and didn't have to rely on network latency to generate realtime preview. Also something which I could use whenever and wherever I wanted, even wihtout Internet! I have written articles about why and how I created Web Maker and how you can benefit from it as a developer.

- FreeCodeCamp: https://medium.freecodecamp.org/web-maker-how-i-built-a-fast-offline-front-end-playground-9fe3629bc86f
- Sitepoint: https://www.sitepoint.com/web-maker-an-offline-browser-based-codepen-alternative/

Make sure to read them if you like to get more behind the scenes of my journey with Web Maker.

Oh yes, I am [running a Patreon campaign](https://www.patreon.com/kushagra) to support my free and open-source projects such as Web Maker. Consider pledging if you use and love Web Maker. 🤗

repository: chinchang/web-maker

gha_language: JavaScript

gha_license_id: MIT

repo_name: chinchang/web-maker


text:
# ${VersionConvert}

Convert version in the numerical format which can be compared.

## Syntax

    ${VersionConvert} "[Version]" "[CharList]" $var

    "[Version]"         ; Version
                        ;
    "[CharList]"        ; List of characters, which will be replaced by numbers
                        ; "abcdefghijklmnopqrstuvwxyz" (default)
                        ;
    $var                ; Result: converted version

Note:

- Converted letters are separated with dot
- If character is non-digit and not in list then it will be converted to dot

## Examples

### Example 1

    Section
        ${VersionConvert} "9.0a" "" $R0
        ; $R0="9.0.01"

        ${VersionConvert} "9.0c" "" $R1
        ; $R1="9.0.03"

        ${VersionCompare} "$R0" "$R1" $R2
        ; $R2="2"   version2 is newer
    SectionEnd

### Example 2

    Section
        ${VersionConvert} "0.15c-9m" "" $R0
        ; $R0="<IP_ADDRESS>.13"

        ${VersionConvert} "0.15c-1n" "" $R1
        ; $R1="<IP_ADDRESS>.14"

        ${VersionCompare} "$R0" "$R1" $R2
        ; $R2="1"   version1 is newer
    SectionEnd

### Example 3

    Section
        ${VersionConvert} "0.15c+" "abcdefghijklmnopqrstuvwxyz+" $R0
        ; $R0="0.15.0327"

        ${VersionConvert} "0.15c" "abcdefghijklmnopqrstuvwxyz+" $R1
        ; $R1="0.15.03"

        ${VersionCompare} "$R0" "$R1" $R2
        ; $R2="1"   version1 is newer
    SectionEnd

## Credits

Written by [Instructor][1]

[1]: http://nsis.sourceforge.net/User:Instructor

license: Zlib

repository: NSIS-Dev/Documentation

branch_name: refs/heads/main

repo_name: NSIS-Dev/Documentation


text:
# 🧐 Consultly!! Private project

> A meeting app building with Ruby on Rails

![screenshot](./app/assets/images/screen-shot.png)

## :notebook: Concept

> Build a basic app with rails to learn the basic concepts of users expirience with devise gem, and for the styles was used Tailwindcss, It consist of making a meeting app where you can use a calendar (simple_calendar gem) to create and show your meetings and Add a payment form for this meetings, also there are a admin user to controll your app and users behavior and finally you can Respond your assitants with a mail, using mailer option from rails.

> View to create a new meeting in your account.

![screenshot](./app/assets/images/new-meeting.png)

> View to see all your meetings in the month.

![screenshot](./app/assets/images/schedule.png)

> View like admin and admin accounts.

![screenshot](./app/assets/images/admin.png)

## 🛠 Built With

- Ruby on Rails
- Tailwindcss
- Postgresql
- Mailers
- Stirpe payment

## 🔧 Getting Started

> To get a local copy up and running follow these simple example steps.

- Go to the main page of the repo.
- Press the "Code" button and get the repo link.
- Clone it using git clone.

### 📝 Prerequisites

- Ruby -v2.7.0p0
- Rails -v<IP_ADDRESS>

### 📝 Setup

 - Open a terminal
 - Copy this code :

        ```
        git clone "put the link from github repo"
        ```

 - Run the program with this code :

        ```
        bundle install
        ```

- Run the program with this code :

        ```
        rails db:create
        rails db:migrate
        ```

- before running ```rails server``` you must run a few more commands: first run ```yarn install --check-files```,
```rails generate devise:install``` then you can configure the Devise gem.
- now you can run ```rails server```
- Stop the program with: "Ctrl + C" (Windows or Linux) or "Command + C"(Apple)

### 📝 How to interact with the app?

- When the program is running go to your browser

- put: localhost:3000/

- Click on login, register and create a new article

- Enjoy the app.

### Usage

- Personal Project - Create a basic blog app just with learning purpose

## 👤 Authors

👤 **Giordano Díaz**

- Github: [@diazgio](https://github.com/diazgio)
- Twitter: [@giordano_diaz](https://twitter.com/giordano_diaz)
- LinkenIn:[LinkenIn](www.linkedin.com/in/Giordano-Diaz)

## 🤝 Contributing

Contributions, issues and feature requests are welcome!

Feel free to check the [issues page](issues/).

## Show your support

Give a ⭐ if you like this project!

## Acknowledgments

- Hat tip to anyone whose code was used
- Inspiration
- etc

## 📝 License

This project is [MIT](LICENSE) licensed.

repository: diazgio/Consultly

branch_name: refs/heads/development

gha_language: Ruby

repo_name: diazgio/Consultly


text:
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
[![GitHub version](https://badge.fury.io/gh/arvenil%2Fninja-mutex.svg)](http://badge.fury.io/gh/arvenil%2Fninja-mutex)
[![Build Status](https://travis-ci.org/arvenil/ninja-mutex.svg?branch=master)](https://travis-ci.org/arvenil/ninja-mutex)
[![HHVM Status](http://hhvm.h4cc.de/badge/arvenil/ninja-mutex.svg)](http://hhvm.h4cc.de/package/arvenil/ninja-mutex)
[![Code Climate](https://codeclimate.com/github/arvenil/ninja-mutex/badges/gpa.svg)](https://codeclimate.com/github/arvenil/ninja-mutex)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/arvenil/ninja-mutex/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/arvenil/ninja-mutex/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/arvenil/ninja-mutex/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/arvenil/ninja-mutex/?branch=master)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/15c5c748-f8d8-4b56-b536-a29a151aac6c/mini.png)](https://insight.sensiolabs.com/projects/15c5c748-f8d8-4b56-b536-a29a151aac6c)
[![Dependency Status](https://gemnasium.com/arvenil/ninja-mutex.svg)](https://gemnasium.com/arvenil/ninja-mutex)
[![Total Downloads](https://img.shields.io/packagist/dt/arvenil/ninja-mutex.svg)](https://packagist.org/packages/arvenil/ninja-mutex)

## About

ninja-mutex is a simple to use mutex implementation for php. It supports different adapters (flock, memcache, mysql, redis, ...) so you can setup it as you wish. All adapters (if set up properly) can be used in multi server environment - in other words lock is shared between web servers.

## Usage

### Mutex

First you need to choose adapter and setup it properly. For example if you choose flock implementation first you need to setup NFS filesystem and mount it on web servers. In this example we will choose memcache adapter:

```php
<?php
require 'vendor/autoload.php';

use NinjaMutex\Lock\MemcacheLock;
use NinjaMutex\Mutex;

$memcache = new Memcache();
$memcache->connect('<IP_ADDRESS>', 11211);
$lock = new MemcacheLock($memcache);
$mutex = new Mutex('very-critical-stuff', $lock);
if ($mutex->acquireLock(1000)) {
    // Do some very critical stuff

    // and release lock after you finish
    $mutex->releaseLock();
} else {
    throw new Exception('Unable to gain lock!');
}
```

### Mutex Fabric

If you want to use multiple mutexes in your project then MutexFabric is the right solution. You setup lock implementor once and you can use as many mutexes as you want!

```php
<?php
require 'vendor/autoload.php';

use NinjaMutex\Lock\MemcacheLock;
use NinjaMutex\MutexFabric;

$memcache = new Memcache();
$memcache->connect('<IP_ADDRESS>', 11211);
$lock = new MemcacheLock($memcache);
$mutexFabric = new MutexFabric('memcache', $lock);
if ($mutexFabric->get('very-critical-stuff')->acquireLock(1000)) {
    // Do some very critical stuff

    // and release lock after you finish
    $mutexFabric->get('very-critical-stuff')->releaseLock();
} else {
    throw new Exception('Unable to gain lock for very critical stuff!');
}

if ($mutexFabric->get('also-very-critical-stuff')->acquireLock(0)) {
    // Do some also very critical stuff

    // and release lock after you finish
    $mutexFabric->get('also-very-critical-stuff')->releaseLock();
} else {
    throw new Exception('Unable to gain lock for also very critical stuff!');
}
```

## Installation

### Composer

Download composer:

    wget -nc http://getcomposer.org/composer.phar

and add dependency to your project:

    php composer.phar require arvenil/ninja-mutex:*

## Running tests

Tests require vfsStream to work. To install it, simply run in project dir:

    wget -nc http://getcomposer.org/composer.phar && php composer.phar install --dev

To run tests type in console:

    phpunit

## Something doesn't work

Feel free to fork project, fix bugs and finally request for pull

gha_language: PHP


text:
# Documentation
This documentation was built with [Sphinx](http://www.sphinx-doc.org) 1.8.4 and [Recommonmark](http://recommonmark.readthedocs.org) 0.5, and uses the [Numpy docstring format](https://numpydoc.readthedocs.io/en/latest/format.html).

## How to build
Ensure all requirements are installed:
```
pip3 install --user -r requirements.txt
```
*Note: User may wish to use Python Virtual Environments or install globally instead of installing packages in their local user directory.  If so, ``--user`` may be omitted.*

Navigate to the `docs` folder:
```
cd docs
```

If necessary, edit the `Makefile`.
Set the `SPHINXBUILD` variable to the appropriate location of `sphinx-build` if not in the default location.

Query which `build` targets are available:
```
make
```

Select a `build` target to compile.  For example, to build `html` documentation:
```
make html
```

repository: USNavalResearchLaboratory/ACME

repo_name: USNavalResearchLaboratory/ACME


text:
---
layout: page
title: About
---

I am a PhD stutent at [Department of Computer Science][1], [Louisiana State University][2] and a Research Assisstant at [Center for Computation and Technology][3].

I am working under supervion of [Dr. Hartmut Kaiser][4].
You can reach me by<EMAIL_ADDRESS>
[1]: http://www.cse.lsu.edu/
[2]: http://www.lsu.edu/
[3]: https://www.cct.lsu.edu/
[4]: https://www.cct.lsu.edu/~hkaiser/


text:
https://confluence.logicline.de/pages/viewpage.action?pageId=85599789

# Salesforce LMA App Cockpit [![Codacy Badge](https://api.codacy.com/project/badge/Grade/23b534ce743a4017a0bba2faaa4ee8ff)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=logiclinegmbh/lma-app-cockpit&utm_campaign=Badge_Grade)

## TL;DR - Show me a demo!

[![](http://img.youtube.com/vi/GTy0Lr19z34/0.jpg)](http://www.youtube.com/watch?v=GTy0Lr19z34 "")

## What is the App Cockpit?

The App Cockpit is a native Salesforce App that extends the Salesforce LMA and helps you monitor the health of your apps and proactively support your subscribers in error cases.

Managed Packages have an option to send out app errors to an email address defined during Package upload. We use this mechanism and let our App receive and parse those emails. In combination with the information in the LMA app, we can perfectly assign each incoming error to a customer account, a package, package version, and license. But we can do more. We also extract information about the type of error and where it occurred.

All this information is stored in a single Custom Object and can be easily used for reporting and sophisticated support workflows.

## Why did you built this?

As a PDO partner, we help many customers every year to get their product ideas out into the AppExchange. But our support doesn't stop with that. Over time we realized that doing support with the LMA app alone is not optimal. So we developed an internal solution which worked well for us.

## Why did you open-source this?

For two reasons. We truly believe in Open Source. We use Open Source in our daily work and think we also have to give back. But we also think that for our customers it's even more trustworthy to know that the source code of the app that they use for support can be checked for bugs by anybody out there.

## How can I use and extends this?

The project was built as a flexible unnamespaced SFDX project. The repo contains all the scripts to automatically build dev scratch orgs with the LMA installed and sample data to play with.

[![Deploy](https://deploy-to-sfdx.com/dist/assets/images/DeployToSFDX.svg)](https://deploy-to-sfdx.com)

From there you can either build Unlocked Packages from it or even push it into a Packaging org using the deployMetadata.sh script.

Feel free to fork the repo and extend it. We would love to get improvements as Pull Request from you. Or create issues when you find a problem but don't want to fix it on your own.

https://confluence.logicline.de/pages/viewpage.action?pageId=85599789

repository: jdgirald/lma-app-cockpit

repo_name: jdgirald/lma-app-cockpit


text:
# pre-commit-rst-lint
Mirror of [`restructuredtext-lint`](https://github.com/twolfson/restructuredtext-lint) for [`pre-commit`](https://pre-commit.com).
See the discussion in [PR #51](https://github.com/twolfson/restructuredtext-lint/pull/51) for details.

### Installation

Add to your `.pre-commit-config.yaml`:
```
-   repo: https://github.com/hoefling/pre-commit-rst-lint
    rev: ''  # Use the sha / tag you want to point at
    hooks:
    -   id: rst-lint
```

Another configuration examples (shamelessly copied from [asottile](https://github.com/asottile)'s comment [here](https://github.com/twolfson/restructuredtext-lint/pull/51#issuecomment-505711533)):

> They can then augment this configuration with additional settings to get more out of the tool, for instance if they wanted to use the pygments highlighting mode they could do the following:
>
> ```
>  -   repo: https://github.com/hoefling/pre-commit-rst-lint
>      rev: ''  # fill in with sha / tag
>      hooks:
>      -   rst-lint
>          additional_dependencies: [pygments]
> ```
> If they wanted to only lint specific rst files they could do this:
>
> ```
>  -   repo: https://github.com/hoefling/pre-commit-rst-lint
>      rev: ''  # fill in with sha / tag
>      hooks:
>      -   rst-lint
>          files: ^changelog/.*\.rst$
> ```
> If they wanted to exclude specific files they could do something like this:
>
> ```
>  -   repo: https://github.com/hoefling/pre-commit-rst-lint
>      rev: ''  # fill in with sha / tag
>      hooks:
>      -   rst-lint
>          exclude: ^doc/sphinx/.*\.rst$
> ```

repository: hoefling/pre-commit-rst-lint

repo_name: hoefling/pre-commit-rst-lint


text:
##README for testing workflow

We use `Github actions` and `Travis` to automate the testing workflow.

###Automation through Github Actions
When there are any `push` or `pull request` events on the `main` branch the job named `build` is triggered. The job runs on a Github-hosted runner which has the `latest ubuntu` image.

The job comprises of fours steps:

```
1. Checkout the code repository
2. Install python version
3. Upgrade pip and install the dependencies from requirements.txt file if available
4. Use PyTest to run the sample unit test defined in test_sample.py
```

###Automation through Travis
On a new commit, the travis job is triggered.
It uses the latest ubuntu version.

The following steps are run through the job:
```
1. Upgrade pip
2. Install pytest
3. Runs the sample test case - test_sample.py
```

### test_sample.py

This file contains sample test cases.
Functions preceeding with `test_` are run by pytest.
We have two sample functions, `test_addition` and `test_substraction` which perform simple arithmetic operations of addition and subtraction.

gha_language: Python


text:
# Fomes epimiltinus (Berk. & Broome) Sacc., 1888 SPECIES

#### Status
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Syll. fung. (Abellini) 6: 207 (1888)

#### Original name
Polyporus epimiltinus Berk. & Broome, 1875

### Remarks
null

repository: mdoering/backbone

path: /life/Fungi/Basidiomycota/Agaricomycetes/Polyporales/Polyporaceae/Tinctoporellus/Tinctoporellus epimiltinus/ Syn. Fomes epimiltinus/README.md

repo_name: mdoering/backbone


text:
# Simple rules:

1. Opening an issue to ask a question is perfectly acceptable.
2. Check thoroughly for duplciates.
3. Don't pull request to rewrite one line or to add a comment.
4. Do pull request to fix memory/cpu/security issues, to add tests, or to fix an issue.
5. Read the Microsoft OTF Table docs before creating a class for a table.
6. Follow the code style.


text:
### Project Overview

 Indian Election Analysis
India's lower house of Parliament,the Lok Sabha, has 543 seats in total.Members of Lok Sabha (House of the People) or the lower house of India's Parliament are elected by being voted upon by all adult citizens of India, from a set of candidates who stand in their respective constituencies. Every adult citizen of India can vote only in their constituency. Candidates who win the Lok Sabha elections are called 'Member of Parliament' and hold their seats for five years or until the body is dissolved by the President on the advice of the council of ministers.

There are more than 700 million voters with more than 800,000 polling stations.

The Lok Sabha election is a very complex affair as it involves a lot of factors. It is this very fact that makes it a perfect topic to analyze.

Currently there are two major parties in India, Bhartiya Janta Party(BJP) and Indian National Congress(INC).

As India is country of diversities, and each region is very different from every other region, there are a lot of regional or state parties having major influences. These parties can either support any of the alliance to make a government or can stay independent.

There are two major alliances, the NDA led by BJP and the UPA led by INC.


text:
---
layout: post
title: "GSoC 2017 Postmortem Part 2: Org Application"
categories: coala
tags: ["gsoc"]
---

In the beginning, there was an organization application.
And with it, the need for someone responsible.
That one was me.
<!--more-->
I always wanted to help with GSoC but felt that my coding skills and
codebase knowledge were not good enough to be a mentor as good as
I'd like to be.
So I followed the call for main admin and on the story went.

Google Application Form
-----------------------
The most obvious piece of the application process is the application
form every organization has to fill on the GSoC page.
The problems I encountered while drafting the first version of our org
profile and "Ten Reasons Why You Should Take coala"-text were
essentially the same as for every application I had ever written.
How does one sell themselves without making things up.

Although coala had two years of GSoC experience, those were as a sub
org under the PSF umbrella.
This year should be the first under our own flag, so everything had to
be perfect.
Again and again I asked for feedback on my drafts and input on things
where I didn't know enough about. Both Lasse and John were very helpful,
both with plenty more GSoC experience than I have.
We felt that we were in a pretty good position.
Our community has a strong connection with the GSoC program, many of our
long time members were students once upon a time.
We had a total of 10 students over the two years with PSF, and from
what I have heard, they were more than pleased with our performance as
an organization, both the students and the PSF.
The only thing that we felt went against us was us being a novice
independent org, and us not having failed any of our students so far.
Yup, this is a thing.
From what I understood, Google expects around 20% failure rate across
all organizations.
If an org deviates from that too much for too long, then they are either
too strict with their students, not strict enough, or there is another
problem with their process.
We actually were quite worried about this point but from what I have
learned, there is no real reason to worry about this.
Document what you and your students are doing and as long as you have
good reasons for the decisions you are making, everything should be
fine in the end.
About the novice part, there wasn't really anything we could do besides
pointing to our past GSoC experience and hoping that Terri Oda, a PSF
GSoC admin, would vouch for us.

Projects Page
-------------

Another, big, part of the application is the projects page.
It is a list of project ideas that students can apply for.
Although it is encouraged that students come up with their own project,
most applications will come from the project list.
And a nice project list is a must have, from what we were told, to get
into GSoC.
We felt that the project page should be the most well fleshed out part
of our application, as it is actually useful during the following parts
of the program and offers a lot of value to the students and us when
the student application phase comes around.
This lead to our web frontend hero Hemang building our new and awesome
[Project Page](https://projects.coala.io).
Before this, we just used a GitHub wiki page with some project drafts
but the new page was much easier to use, gave a better overview about
the projects and it gives us the possibility to add features to it in
the future.
During this early phase, we included the old projects from the wiki and
asked mentors and community members for other projects ideas they might
be interested in mentoring.
For those who haven't read any of the project ideas on our page, the
structure always is something like this:
Introduction and motivation, sometimes followed by some additional
information about how to solve the problem if we already had some idea
about it.
Then we show a time line following the GSoC 4 phase model, that holds
some milestones and gives a rough idea about when to deliver the single
parts.
Finally, we link all additional information we have about the project,
like issues or cEPs, add mentors as contact persons, and some more meta
information.
In addition to the project ideas the page also holds a faq section,
where we started to collect questions we received again and again or
just felt were important.
We actually tried to let the student's add the questions and answers
to the faq themselves to include them into our process and also to make
sure they actually understood our answer and thus to double check if
our answer was good enough or if maybe we need a better explanation.
We had close to twenty project idea drafts at this point and felt that
we were more than ready to hand everything in to Google and be accepted.
Before we move on to the next part, I want to point out that we also
built the projects page so other orgs could use it and we have received
some good feedback on it.

FOSSDEM and Feedback from Stephanie
-----------------------------------

In February, a few weeks before the application deadline, we went to
FOSSDEM with coala.
We had a stand where we promoted what we did but most important, our
stand was right next to the GSoC stand.
A great opportunity to get feedback and ask some questions we figured,
and so I walked over in a calmer minute to show Stephanie what we had
so far.
Starting with the projects page, she liked it a lot.
She liked the idea of it and how it was structured and could help to
introduce students even easier.
The only improvement she asked for with it were the project
descriptions.
Flesh out the motivation for most projects and just write a little more
to make it easier for students was what I took away for the projects
age.
But overall this part gave me a very good feeling!

Then we talked about our chances to get into the program with the
experience we had under our belt and our expectations and wishes for
slots we would get.
As I said before, we had 10 students over the last two seasons.
First 2, then 8.
We felt, that we could probably grow some more with the mentor power we
had amassed but also didn't expect too much as we had some challenges
coming up, that we didn't have the last two times.
What I asked was probably something along the lines of "how high are
our chances to get around 12 students this year with what I just showed
you + improvements I'll implement?".
And here is where the not-so-fun part started.
She essentially looked at me as if I asked for a million dollars out of
nowhere.
Turns out, that first time organizations usually get 1 or 2 students.
And even with our past experience as a sub org, we kind of counted as
a first time org.
I pointed out that we had 8 students under PSF last year and received
great feedback from their admins for our work and Stephanie couldn't
believe that we did get such an enormous number of students as such a
young org.
I came out of that part of our conversation with the feeling that we'd
probably not get more than 4 slots no matter what we did.
Not a great takeaway.

Implementing Feedback
---------------------
I rewrote a lot of our application texts to focus more on the things
Stephanie pointed out as important factors after we returned but the
main part of work I did was essentially rewriting all twenty something
project proposals we had.
Although I wrote some of them myself, most of them were actually written
by students or mentors and I did all the review work.
The reason or this was that even though I probably would have been
faster just writing everything myself, I wouldn't be able to get enough
reviews to merge everything in time.
So the solution was to poke students that were interested in the
projects and mentors to rewrite it and me reviewing it.

During this time I also struggled with the expected slots we would get.
While yes, we would finally be our own organization, with all the pros
that would bring with it long term, it also felt like a step backwards
to loose students slots compared to last year.
But the fact that we couldn't grow further under the PSF and had plans
to act as an umbrella for smaller linter projects made the investment
in our long term growth worth it in our eyes.
I should probably add that we had more than 5 newcomers per week during
this time that were interested in GSoC with us.
This meant that the newcomers from one week might be more than we would
get.
And there were quite some students that came to us end of last year and
had contributed a lot.
Hard time deciding whom to take on the horizon already.

After completing the projects rewrite we called it done and handed
everything in for the final time.
Now all that was left was to wait and get to know the possible students.

Result Day, Slots and Thoughts
------------------------------
We were accepted.
And although it doesn't quite fit here chronologically, we received 10
slots.
We were happy when we were accepted and a huge weight left my shoulders.
But the real joy came when we received those 10 slots.
Apparently Terri gave us one hell of a recommendation and all the
mentors we had collected and project ideas we had prepared were worth
something after all.
John, one of the other mentors, also met Stephanie at FOSSASIA and kind
of implied that getting only two slots wouldn't work for us so maybe
that also helped.
Regardless of how we did it, yeay for the slots!

So what do I think about how everything went down?
I feel like the projects page was a great idea and will serve us (and
maybe other orgs) well in the future.
There are some downsides to it in my opinion that I will cover in the
next part more in depth but the main thing is that all those super
defined projects left the students with *nothing* to think about in some
cases.
In the future, we will focus more on presenting the problem and why we'd
like to fix it and less about the how to fix it in detail.
This way we give students a chance to shine during their application
phase by working on the specifics with the respective mentors and take
some of the work off of us.

The part where we included students in writing the projects and faq
entries on the other hand was great.
It is definitely more work than just doing it yourself but it works as
a first identifier for very good students.
They will be happy to help defining projects, already starting to do
research on it and discuss the details with possible mentors.
Doing this in a more structured way will probably something we will try
to do in future years.

About the meeting with Stephanie at FOSSDEM, I would recommend that to
everyone!
Stephanie is a lovely person and helped us a lot with her feedback I
feel.
She is also just nice to talk to :).

Overall I feel like this part of GSoC went pretty well and without real
problems beside our panic of getting too few slots.
Things won't stay this rosy in the next phase sadly so if you want some
drama and more interesting "things we could have done better" things,
make sure to come back.
I'm not sure when I will find the time to finish the next part as
I have some university to catch up on and it takes me a good 2 hours to
 write one of these, at least so far, but I'll try to keep at least a
weekly schedule for this series until I am done.

Thanks again to Terri Oda from the PSF and Stephanie Taylor from Google
for your support during this phase that definitely helped us to get
into GSoC and learn a lot as an org.

gha_language: HTML


text:
# Hello World

This is a starter application. It contains a basic manifest file with no
additional permissions. The manifest denotes the launch_path, unlike Google's
packaged app infrastructure there is no background script that needs to be loaded.

detailed below:

{
  "name": "Hello World",
  "description": "Hello World",
  "launch_path": "/index.html",
  "icons": {
      "128": "icon_128.png"
  },

## Resources

https://marketplace.firefox.com/developers/docs/packaged

repository: dclarke/firefox-os-sample-apps

repo_name: dclarke/firefox-os-sample-apps