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

"Wedge" recipe for PolarAxis #4790

Open
cvigilv opened this issue Feb 13, 2025 · 0 comments
Open

"Wedge" recipe for PolarAxis #4790

cvigilv opened this issue Feb 13, 2025 · 0 comments

Comments

@cvigilv
Copy link

cvigilv commented Feb 13, 2025

I'm helping on the development of a plotting library and I came up with the following recipe to plot "wedges"/regions/polygons (not sure how to name it) inspired in the likes of vspan and hspan:

function polarpoly end
function polarpoly! end

Makie.@recipe(PolarPoly, r_min, r_max, theta_min, theta_max) do scene
    Makie.Attributes(
        alpha = @something(Makie.theme(scene, :alpha), 0.5),
        color = @something(Makie.theme(scene, :color), :blue),
        resolution = 1.0,
    )
end

function Makie.plot!(plt::PolarPoly)
    # Check if inputs are correct
    @assert length(plt.r_min[]) == length(plt.r_max[]) == length(plt.theta_min[]) == length(plt.theta_max[]) "Mismatch between number of values for polygon"

    # Allow user to give multiple colors as input
    # NOTE: This is implemented like this due to CairoMakie not respecting the `alpha`
    # parameter. Refer to https://github.com/MakieOrg/Makie.jl/issues/4614 for more
    # information
    if typeof(plt.color[]) == Symbol
        plt.color[] = fill((plt.color[], plt.alpha[]), length(plt.r_min[]))
    elseif typeof(plt.color[]) == Tuple{Any,AbstractFloat}
        plt.color[] = fill((first(plt.color[]), last(plt.color[]) * plt.alpha[]), length(plt.r_min[]))
    else
        c_array = Vector(undef, length(plt.color[]))
        for (i, c) in enumerate(plt.color[])
            if typeof(c) == Tuple{Any,AbstractFloat}
                c_array[i] = (first(c), last(c) * plt.alpha[])
            else
                c_array[i] = (c, plt.alpha[])
            end
        end
        plt.color[] = c_array
    end
    @assert length(plt.color[]) == length(plt.r_min[]) "Mismatch between number of values and colors"

    for (i, (r_min, r_max, theta_min, theta_max)) in enumerate(zip(plt.r_min[], plt.r_max[], plt.theta_min[], plt.theta_max[]))
        # Compute curved segments to connect
        segments_theta = range(
            theta_min,
            theta_max,
            length = trunc(Int, abs(rad2deg(theta_min - theta_max)) * plt.resolution[])
        )
        r_min = fill(r_min, length(segments_theta))
        r_max = fill(r_max, length(segments_theta))

        # Convert polar coordinates to cartesian
        x_inner = @. r_min * cos(segments_theta)
        y_inner = @. r_min * sin(segments_theta)
        x_outer = @. r_max * cos(segments_theta)
        y_outer = @. r_max * sin(segments_theta)

        # Combine points to form a closed polygon
        x = vcat(x_inner, reverse(x_outer), x_inner[1])
        y = vcat(y_inner, reverse(y_outer), y_inner[1])

        poly!(plt, Point2f.(zip(x, y)), alpha = plt.alpha[]; color=plt.color[][i])
    end
end

Example:

# Usage example:
begin
    fig = Figure()
    ax = PolarAxis(fig[1, 1])
    polarpoly!(
        ax,
        0:17,
        1:18,
        range(0, 2π-π/18, length = 18),
        range/18, 2π, length = 18),
        color = [(:blue,alpha) for alpha in range(0.0, 1.0, 18)]
    )
    fig
end

Image

The issue is, I'm unsure how to create the PR to add this, or if this is even neccesary or already implemented (from my search through the documentation and code base, I found nothing like this).

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