fill_between несколько внутренних и внешних полигонов на полярной (радарной) диаграмме - PullRequest
0 голосов
/ 26 марта 2020

У меня есть несколько повторов, каждый с одним значением для каждой из 5 переменных (тонкие темные линии на графиках ниже). Я хочу, чтобы «конверт» данных был заштрихован (внутреннее и внешнее маскирование выполнено в Inkscape):

matplotlib output with masking

То, что я смог изобразить out (используя минимальное и максимальное значения для каждой переменной): matplotlib output...shading based on min/max

на основе:

import numpy as np
import random
import pandas as pd
from math import pi
from matplotlib import pyplot as plt
import matplotlib

outpath = "C:\\"
size = 30 # number of elements
var_lst = ["T", "W", "A", "S", "E"]   # var labels

# generate lists of example data for each var
trn = np.random.uniform(low=1.2, high=4.6, size=size).round(1)
wid = np.random.uniform(low=0.5, high=3.2, size=size).round(1)
ang = np.random.uniform(low=0.5, high=2.9, size=size).round(1)
spd = np.random.uniform(low=1.1, high=3.6, size=size).round(1)
elv = np.random.uniform(low=3.2, high=4.9, size=size).round(1)

# generate list of angles for plotting each variable
angles = [i / float(len(var_lst)) * 2 * pi for i in range(len(var_lst))]

# use dataframe to transform data
df = pd.DataFrame(dict(zip(var_lst,[trn,wid,ang,spd,elv])))

# generate list of element-wise lists
val_lst = df.values.tolist()

# define shaded region from min and max values of each element
am_min = []
am_max = []

for c in var_lst:
    min = df[c].min()
    max = df[c].max()
    am_min.append(min)
    am_max.append(max)

def copy_first(ls):
    '''copies first value of list and appends to end of same list'''
    ls.append(ls[0])
    return(ls)

# run function to close plotting loop 
for a in [[am_min,am_max,angles],val_lst]:
    for b in a:
        copy_first(b)

# plotting
fig,ax = plt.subplots(1,1,figsize=(10,10)) 

# # plot 100% of width and height extents...use as argument for all axes
ax_coords = [0, 0, 1, 1]

# # create polar axis
ax_polar =  fig.add_axes(ax_coords, projection='polar',label="ax polar")

# plot minima and maxima by property and fill ambient region
ax_polar.fill_between(angles, am_max, am_min, color="gainsboro", alpha=0.7)
ax_polar.fill_between(angles, am_min, am_max, color="gainsboro", alpha=0.7)

# plot individual elements
for v in val_lst:
    ax_polar.plot(angles, v, color='grey', linestyle='solid', linewidth=1)  

# turn off axes, labels, etc
ax_polar.axis('off')
ax.axis('off')

Есть ли краткий способ сделать то, что я хочу с fill_between (при условии, что я мог бы определить, какие линии влияли на внутренний и внешний периметры)? Нужно ли определять координаты для каждого перегиба периметра? выполнить какую-то геообработку на элементах в geo pandas? Другой?

Приветствия

РЕДАКТИРОВАТЬ 27 марта ...

Я знаю, что могу использовать ax_polar.fill внутри элемента 'для' l oop. Хотя это дает приемлемый результат для внешнего периметра, оно затеняет отверстие для пончика.

...