Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion of improved version of get_contourf_levels() concerning the contour labels and float formatting #19

Open
AndreasLuckert opened this issue Aug 10, 2020 · 0 comments

Comments

@AndreasLuckert
Copy link

As I coulnd't figure out how exactly to start a pull request here (never done that before actually),
I'm going to post my customized version of the function get_contourf_levels().
This will allow for passing a specific float-format of desire which will affect the labeling of the contours.
The formatting of these string-labels itself has also been improved.

def get_contourf_levels(levels, extend, float_fmt="%.2f"):
    # Latest implementation using f-strings and improved formatting of all ranges
    mid_levels = [
        f"({float_fmt % levels[i]} - {float_fmt % levels[i+1]})"
        for i in range(len(levels) - 1)
    ]
    # Previous implementation:
    #mid_levels = [float_fmt % levels[i] + '-' + float_fmt % levels[i+1] for i in range(len(levels)-1)]

    # i) Decide whether to modify the mid-levels list
    if extend == 'both':
        return [
            f"< {float_fmt % levels[0]}", *mid_levels,
            f"> {float_fmt % levels[-1]}"
        ]
    elif extend == 'max':
        return [*mid_levels, f"> {float_fmt % levels[-1]}"]
    elif extend == 'min':
        return [f"< {float_fmt % levels[0]}", *mid_levels]

    # ii) Return unchanged
    else:
        return mid_levels

To pass the new parameter float_fmt, the two contourf-geojson functions also need to be adjusted a bit:

def contourf_to_geojson_overlap(contourf,
                                geojson_filepath=None,
                                min_angle_deg=None,
                                ndigits=5,
                                unit='',
                                stroke_width=1,
                                fill_opacity=.9,
                                geojson_properties=None,
                                strdump=False,
                                serialize=True,
                                float_fmt="%.2f"):

    """Transform matplotlib.contourf to geojson with overlapping filled contours."""
    polygon_features = []
    contourf_idx = 0

    # Pass (custom) float format to extract the contour-levels
    contourf_levels = get_contourf_levels(contourf.levels,
                                          contourf.extend,
                                          float_fmt=float_fmt)

    for collection in contourf.collections:
        color = collection.get_facecolor()
        for path in collection.get_paths():
            for coord in path.to_polygons():
                if min_angle_deg:
                    coord = keep_high_angle(coord, min_angle_deg)
                coord = np.around(coord, ndigits) if ndigits else coord
                polygon = Polygon(coordinates=[coord.tolist()])
                fcolor = rgb2hex(color[0])
                properties = set_contourf_properties(
                    stroke_width, fcolor, fill_opacity,
                    contourf_levels[contourf_idx], unit)
                if geojson_properties:
                    properties.update(geojson_properties)
                feature = Feature(geometry=polygon, properties=properties)
                polygon_features.append(feature)
        contourf_idx += 1
    feature_collection = FeatureCollection(polygon_features)
    return _render_feature_collection(feature_collection, geojson_filepath,
                                      strdump, serialize)

def contourf_to_geojson(contourf,
                        geojson_filepath=None,
                        min_angle_deg=None,
                        ndigits=5,
                        unit='',
                        stroke_width=1,
                        fill_opacity=.9,
                        fill_opacity_range=None,
                        geojson_properties=None,
                        strdump=False,
                        serialize=True,
                        float_fmt="%.2f"):
    """Transform matplotlib.contourf to geojson with MultiPolygons."""

    if fill_opacity_range:
        variable_opacity = True
        min_opacity, max_opacity = fill_opacity_range
        opacity_increment = (max_opacity - min_opacity) / len(contourf.levels)
        fill_opacity = min_opacity
    else:
        variable_opacity = False
    polygon_features = []

    # Pass (custom) float format to extract the contour-levels
    contourf_levels = get_contourf_levels(contourf.levels,
                                          contourf.extend,
                                          float_fmt=float_fmt)

    for coll, level in zip(contourf.collections, contourf_levels):
        color = coll.get_facecolor()
        muli = MP(coll, min_angle_deg, ndigits)
        polygon = muli.mpoly()
        fcolor = rgb2hex(color[0])
        properties = set_contourf_properties(stroke_width, fcolor,
                                             fill_opacity, level, unit)
        if geojson_properties:
            properties.update(geojson_properties)
        feature = Feature(geometry=polygon, properties=properties)
        polygon_features.append(feature)
        if variable_opacity:
            fill_opacity += opacity_increment
    feature_collection = FeatureCollection(polygon_features)
    return _render_feature_collection(feature_collection, geojson_filepath,
                                      strdump, serialize)
@AndreasLuckert AndreasLuckert changed the title Improved version of get_contourf_levels() affecting the contour labels and float formatting Suggestion of improved version of get_contourf_levels() concerning the contour labels and float formatting Aug 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant