How to plot horizontal lines with text (i.e. a label) on a polar coordinates matplotlib plot? (Python)

O.rka

I'm trying to label the nodes in my polar coordinates plot. There are 3 "axes" that are split and I have figured out how to use the quadrants to select which nodes to label. However, I can't figure out how to align these on the edge of the plot (i.e. axis_maximum). I have spent several hours trying to figure this out. My best option was to pad with . on the left or right but this was a fixed number and got messy when there were too many points. Also, this method went too far outside the "circular" nature of the plot when there were a lot of points. I did some trigonometry to figure out the lengths for everything but this was difficult to implement using text units such as ..

If anyone can help it would be greatly appreciated. I showed what the plot looks like below and then added in red what I am trying to implement. label in the mock figure corresponds to name_node in the for-loop. Ideally I would like to steer away from using characters like . and would rather use an actual matplotlib Line object so I can specify linestyle like : or -.

In summary, I would like to do the following:

  1. Add horizontal lines stretching from my "axis" to the outer edge of the plot (either the right or the left depending on the quadrant)
  2. At the end of the line in (1), I would like to add the name_node text.

EDIT:

  • I've added an attempt to overlay a cartesian axis and then plot the lines on this. No success.

import numpy as np
from numpy import array # I don't like this but it's for loading in the pd.DataFrame
import pandas as pd 
import matplotlib.pyplot as plt
df = pd.DataFrame({'node_positions_normalized': {'iris_100': 200.0, 'iris_101': 600.0, 'iris_102': 1000.0, 'iris_0': 200.0, 'iris_1': 600.0, 'iris_2': 1000.0, 'iris_50': 200.0, 'iris_51': 600.0, 'iris_52': 1000.0}, 'theta': {'iris_100': array([5.42070629, 6.09846678]), 'iris_101': array([5.42070629, 6.09846678]), 'iris_102': array([5.42070629, 6.09846678]), 'iris_0': array([1.23191608, 1.90967657]), 'iris_1': array([1.23191608, 1.90967657]), 'iris_2': array([1.23191608, 1.90967657]), 'iris_50': array([3.32631118, 4.00407168]), 'iris_51': array([3.32631118, 4.00407168]), 'iris_52': array([3.32631118, 4.00407168])}})
axis_maximum = df["node_positions_normalized"].max()
thetas = np.unique(np.stack(df["theta"].values).ravel())


def pol2cart(rho, phi):
    x = rho * np.cos(phi)
    y = rho * np.sin(phi)
    return(x, y)

def _get_quadrant_info(theta_representative):
    # 0/360
    if theta_representative == np.deg2rad(0):
        quadrant = 0
    # 90
    if theta_representative == np.deg2rad(90):
        quadrant = 90
    # 180
    if theta_representative == np.deg2rad(180):
        quadrant = 180
    # 270
    if theta_representative == np.deg2rad(270):
        quadrant = 270

    # Quadrant 1
    if np.deg2rad(0) < theta_representative < np.deg2rad(90):
        quadrant = 1
    # Quadrant 2
    if np.deg2rad(90) < theta_representative < np.deg2rad(180):
        quadrant = 2
    # Quadrant 3
    if np.deg2rad(180) < theta_representative < np.deg2rad(270):
        quadrant = 3
    # Quadrant 4
    if np.deg2rad(270) < theta_representative < np.deg2rad(360):
        quadrant = 4
    return quadrant
    
    
with plt.style.context("seaborn-white"):
    fig = plt.figure(figsize=(8,8))
    ax = plt.subplot(111, polar=True)
    ax_cartesian = fig.add_axes(ax.get_position(), frameon=False, polar=False)
    ax_cartesian.set_xlim(-axis_maximum, axis_maximum)
    ax_cartesian.set_ylim(-axis_maximum, axis_maximum)

    # Draw axes
    for theta in thetas:
        ax.plot([theta,theta], [0,axis_maximum], color="black")
        
    # Draw nodes
    for name_node, data in df.iterrows():
        r = data["node_positions_normalized"]
        for theta in data["theta"]:
            ax.scatter(theta, r, color="teal", s=150, edgecolor="black", linewidth=1, alpha=0.618)
        # Draw node labels
        quadrant = _get_quadrant_info(np.mean(data["theta"]))
 
        # pad on the right and push label to left
        if quadrant in {1,4}:
            theta_anchor_padding = min(data["theta"])
        # pad on left and push label to the right
        if quadrant in {2,3}:
            theta_anchor_padding = max(data["theta"])
            
        # Plot
        ax.text(
            s=name_node,
            x=theta_anchor_padding,
            y=r,
            horizontalalignment="center",
            verticalalignment="center",
        )
    
    ax.set_rlim((0,axis_maximum))
    
    # Convert polar to cartesian and plot on cartesian overlay?
    xf, yf = pol2cart(theta_anchor_padding, r) #fig.transFigure.inverted().transform(ax.transData.transform((theta_anchor_padding, r)))
    ax_cartesian.plot([xf, axis_maximum], [yf, yf])

enter image description here

Stef

You can use annotate instead of text, this allows you to specify the text coordinates and the text coordinate system independently of the point coordinates. We place the text in figure coordinates (0 to 1, see here for details). It's important to get the transformation from data to figure coordinates after the r limit is set.

with plt.style.context("seaborn-white"):
    fig = plt.figure(figsize=(8,8))
    ax = plt.subplot(111, polar=True)
    ax.set_rlim((0,axis_maximum))
    ann_transf = ax.transData + fig.transFigure.inverted() 

    # Draw axes
    for theta in thetas:
        ax.plot([theta,theta], [0,axis_maximum], color="black")
    
    
    # Draw nodes
    for name_node, data in df.iterrows():
        r = data["node_positions_normalized"]
        for theta in data["theta"]:
            ax.scatter(theta, r, color="teal", s=150, edgecolor="black", linewidth=1, alpha=0.618)
        # Draw node labels
        quadrant = _get_quadrant_info(np.mean(data["theta"]))
 
        # pad on the right and push label to left
        if quadrant in {1,4}:
            theta_anchor_padding = min(data["theta"])
        # pad on left and push label to the right
        if quadrant in {2,3}:
            theta_anchor_padding = max(data["theta"])
            
        # Plot
        _,y = ann_transf.transform((theta_anchor_padding, r))
        ax.annotate(name_node, 
                    (theta_anchor_padding,r), 
                    (0.91 if quadrant in {1,4} else 0.01, y),
                    textcoords='figure fraction',
                    arrowprops=dict(arrowstyle='-', color='r'),
                    color='r',
                    verticalalignment='center'
        )

enter image description here

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

How to plot polar coordinates in R?

分類Dev

How to plot a polar plot?

分類Dev

r - how to add label in corner of polar plot

分類Dev

Polar plot in Matplotlib not centered

分類Dev

Matplotlib: how to set a tick label above a plot

分類Dev

matplotlib shift pcolormesh plot to symmetrized coordinates

分類Dev

How to plot contours from a polar stereographic grib2 file in Python

分類Dev

Can I have multiple matplotlib plot windows in python interactive mode?

分類Dev

How do I plot for Multiple Linear Regression Model using matplotlib

分類Dev

horizontal offset for categorical plot

分類Dev

python matplotlib plot table with multiple headers

分類Dev

Matplotlib regression scattered plot using Python?

分類Dev

How to save a greyscale matplotlib plot to numpy array

分類Dev

How to add a legend to matplotlib scatter plot

分類Dev

How to repeat a plot in different subplots in matplotlib?

分類Dev

How to generate several legends for single plot matplotlib

分類Dev

How do I plot GFS grib2 data with Python?

分類Dev

Scaling the axes in a polar plot of ggplot individually?

分類Dev

How to draw lines with lines() without preceding call to plot() in R

分類Dev

How can I copy style of an existing Line2D object to a plot() call? (matplotlib)

分類Dev

Matplotlib plot settings

分類Dev

Matplotlib: Check for empty plot

分類Dev

Ticklabels inside a plot in matplotlib

分類Dev

How to plot simple plot from DataFrame in Python Pandas?

分類Dev

How to change x-label in plot without showing the previous values?

分類Dev

How to set and display x/y label with pandas plot in ipython notebook?

分類Dev

The x label of a box plot is shifted

分類Dev

Moving x-axis in matplotlib during real time plot (python)

分類Dev

Plot start-end time slots - matplotlib python

Related 関連記事

  1. 1

    How to plot polar coordinates in R?

  2. 2

    How to plot a polar plot?

  3. 3

    r - how to add label in corner of polar plot

  4. 4

    Polar plot in Matplotlib not centered

  5. 5

    Matplotlib: how to set a tick label above a plot

  6. 6

    matplotlib shift pcolormesh plot to symmetrized coordinates

  7. 7

    How to plot contours from a polar stereographic grib2 file in Python

  8. 8

    Can I have multiple matplotlib plot windows in python interactive mode?

  9. 9

    How do I plot for Multiple Linear Regression Model using matplotlib

  10. 10

    horizontal offset for categorical plot

  11. 11

    python matplotlib plot table with multiple headers

  12. 12

    Matplotlib regression scattered plot using Python?

  13. 13

    How to save a greyscale matplotlib plot to numpy array

  14. 14

    How to add a legend to matplotlib scatter plot

  15. 15

    How to repeat a plot in different subplots in matplotlib?

  16. 16

    How to generate several legends for single plot matplotlib

  17. 17

    How do I plot GFS grib2 data with Python?

  18. 18

    Scaling the axes in a polar plot of ggplot individually?

  19. 19

    How to draw lines with lines() without preceding call to plot() in R

  20. 20

    How can I copy style of an existing Line2D object to a plot() call? (matplotlib)

  21. 21

    Matplotlib plot settings

  22. 22

    Matplotlib: Check for empty plot

  23. 23

    Ticklabels inside a plot in matplotlib

  24. 24

    How to plot simple plot from DataFrame in Python Pandas?

  25. 25

    How to change x-label in plot without showing the previous values?

  26. 26

    How to set and display x/y label with pandas plot in ipython notebook?

  27. 27

    The x label of a box plot is shifted

  28. 28

    Moving x-axis in matplotlib during real time plot (python)

  29. 29

    Plot start-end time slots - matplotlib python

ホットタグ

アーカイブ