Создание небольших полярных диаграмм внутри диаграммы рассеяния- Python - PullRequest
1 голос
/ 18 июня 2020

Я отредактировал, чтобы сделать свой вопрос более конкретным c. У меня есть набор данных с 4 переменными: 'x', 'y', 'Length' и 'Direction'. Переменная «Направление» - полярная. Меня просят построить диаграмму рассеяния, а затем преобразовать каждую точку в небольшой полярный график, отражающий ее длину и направление. Я пробовал делать векторы с помощью колчана, но результат оказался неудовлетворительным. Я прилагаю свой код для диаграммы рассеяния, Sample DataFrame и png, который показывает желаемый результат. scatterplot with each point changed into a small polar plot

bc = pd.DataFrame({'x':[2,4,6], 'y':[1,3,5], 'Length':[10,25,23], 'Direction':[-86,-85,-80]})   
plt.figure(figsize=(14, 7))
ax = sns.scatterplot(x="x", y="y", data=bc)
plt.title('Scatter Plot of x and y')

1 Ответ

3 голосов
/ 19 июня 2020

Вот возможный подход. Треугольник создается с заданными x и y с учетом угла и длины. Если ориентация по умолчанию (нулевой угол, указывающий вправо) не является желаемой, к синусам и / или косинусам можно добавить знаки минус. Кроме того, роль синусов и косинусов можно менять местами, чтобы отразить угол по диагонали.

Чтобы углы не выглядели деформированными, можно использовать set_aspect('equal').

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

bc = pd.DataFrame({'x': [2, 4, 6], 'y': [1, 3, 5], 'Length': [10, 25, 23], 'Direction': [-86, -85, -80]})
plt.figure(figsize=(14, 7))

delta = 15  # half of the aperture angle (in degrees)
length_factor = 1 / bc['Length'].max()  # this makes the longest 1 unit long
for x, y, length, dir in zip(bc['x'], bc['y'], bc['Length'], bc['Direction']):
    for is_backgr in (True, False):
        if is_backgr:
            arc_angles = np.linspace(dir + delta, dir + 360 - delta, 32)
        else:
            arc_angles = np.linspace(dir - delta, dir + delta, 10)
        c_arr = np.cos(np.radians(arc_angles))
        s_arr = np.sin(np.radians(arc_angles))
        r = length * length_factor
        x_arr = x + np.pad(c_arr * r, (1, 1))
        y_arr = y + np.pad(s_arr * r, (1, 1))
        plt.fill(x_arr, y_arr, c='grey' if is_backgr else 'crimson', alpha=0.2)
        plt.plot(x_arr, y_arr, c='black' if is_backgr else 'crimson', lw=0.5 if is_backgr else 2)
ax = sns.scatterplot(x="x", y="y", data=bc, s=100)
ax.set_title('Scatter Plot of x and y')
ax.set_aspect('equal')
plt.show()

example plot

...