如何在极坐标 matplotlib 图上绘制带有文本(即标签)的水平线? (Python)

2023-12-04

我正在尝试在极坐标图中标记节点。有 3 个被分割的“轴”,我已经弄清楚如何使用象限来选择要标记的节点。但是,我不知道如何在图的边缘对齐这些(即axis_maximum)。我花了几个小时试图弄清楚这一点。我最好的选择是用.在左边或右边,但这是一个固定的数字,当点太多时会变得混乱。而且,当有很多点时,这种方法太过脱离了情节的“循环”性质。我做了一些三角学计算出所有内容的长度,但这很难使用文本单元来实现,例如..

如果有人可以提供帮助,我们将不胜感激。我展示了下面的情节,然后用红色添加了我想要实现的内容。label模拟图中对应于name_node在for循环中。理想情况下,我想避免使用类似的字符.并且宁愿使用实际的matplotlib Line对象,以便我可以指定linestyle like : or -.

总而言之,我想做到以下几点:

  1. 添加从我的“轴”延伸到图的外边缘的水平线(右侧或左侧取决于象限)
  2. 在 (1) 行的末尾,我想添加name_node text.

EDIT:

  • 我添加了尝试覆盖笛卡尔轴,然后在其上绘制线条的尝试。没有成功。

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


您可以使用annotate代替text,这允许您独立于点坐标来指定文本坐标和文本坐标系。我们将文本放置在图形坐标中(0 to 1, see here了解详情)。从数据到图形坐标的转换很重要after the r已设置限制。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在极坐标 matplotlib 图上绘制带有文本(即标签)的水平线? (Python) 的相关文章

  • 即使页面未完全加载,我们也可以使用 Selenium 获取页面源吗(TimeoutException: Message: timeout)?

    即使遇到 TimeoutException Message timeout 也能获取页面源码吗 当我调用 driver page source 时 有时无法加载整页 但我只需要它的部分信息 尚未确定 所以我只想在任何情况下保存页面 是否可以
  • Python有条件求解时滞微分方程

    我在用dde23 of pydelay包来求解延迟微分方程 我的问题 如何有条件地编写方程 例如目标方程有两个选项 when x gt 1 dx dt 0 25 x t tau 1 0 pow x t tau 10 0 0 1 x othe
  • Kivy - 文本换行工作错误

    我正在尝试在 Kivy 1 8 0 应用程序中换行文本 当没有太多文字时 一切正常 但如果文本很长并且窗口不是很大 它只是剪切文本 这是示例代码 vbox BoxLayout orientation vertical size hint y
  • Python 2.7 将比特币私钥转换为 WIF 私钥

    作为一名编码新手 我刚刚完成了教程 教程是这样的 https www youtube com watch v tX XokHf nI https www youtube com watch v tX XokHf nI 我想用 1 个易于阅读
  • 为什么我的代码不能根据字典解码加密字符串?

    我有一本字典 其中包含代表字母的键和值 例如一个简单的 DICT CODE b g n a p o x d t y 我收到了一个加密代码 并将该字符串转换为一个列表 其中每个项目都是一个单词 我需要根据字典中的项目来解决它 代码示例是 wo
  • 更新 Sqlalchemy 中的多个列

    我有一个在 Flask 上运行的应用程序 并使用 sqlalchemy 与数据库交互 我想用用户指定的值更新表的列 我正在使用的查询是 def update table value1 value2 value3 query update T
  • 查找模块中显式定义的函数 (python)

    好的 我知道您可以使用 dir 方法列出模块中的所有内容 但是有什么方法可以仅查看该模块中定义的函数吗 例如 假设我的模块如下所示 from datetime import date datetime def test return Thi
  • 如何在 Python 3 中循环遍历集合,同时从集合中删除项目

    这是我的情况 我有一个list set 哪个并不重要 movieplayer我想调用的对象 preload 功能开启 该预加载函数可以立即返回 但希望将来返回一点 我想存储这个电影播放器 集合 表明它们尚未预加载 然后循环它们 调用prel
  • 可以用 Django 制作移动应用程序吗?

    我想知道我是否可以在我的网站上使用 Django 代码 并以某种方式在移动应用程序 Flutter 等框架中使用它 那么是否可以使用我现在拥有的 Django 后端并在移动应用程序中使用它 所以就像models views etc 是的 有
  • 如何将 self 传递给装饰器?

    我该如何通过self key下面进入装饰器 class CacheMix object def init self args kwargs super CacheMix self init args kwargs key func Cons
  • 与 while 循环一样,如何跳过 for 循环中的步骤?

    我尝试像 while 循环一样跳过 for 循环中的几个步骤 在 while 循环中 步骤根据特定条件进行调整 如下面的代码所示 i 0 while i lt 10 if i 3 i 5 else print i i i 1 result
  • django-admin.py makemessages 不起作用

    我正在尝试翻译一个字符串 load i18n trans Well Hello there how are you to Hola amigo que tal 我的 settings py 文件有这样的内容 LOCALE PATHS os
  • 乘以行并按单元格值附加到数据框

    考虑以下数据框 df pd DataFrame X a b c d Y a b d e Z a b c d 1 2 1 3 df 我想在 列中附加数字大于 1 的行 并在该行中的数字减 1 df 最好应该 然后看起来像这样 或者它可能看起来
  • 具有屏蔽无效值的 pcolormesh

    我试图将一维数组绘制为 pcolormesh 因此颜色沿 x 轴变化 但每个 x 的 y 轴保持不变 但我的数据有一些错误值 因此我使用屏蔽数组和自定义颜色图 其中屏蔽值设置为蓝色 import numpy as np import mat
  • Pandas style.bar 颜色基于条件?

    如何渲染其中一列的 Pandas dfstyle bar color属性是根据某些条件计算的 Example df style bar subset before after color ff781c vmin 0 0 vmax 1 0 而
  • 使用 matplotlib.animation 从 CSV 文件实时绘图 - 数据绘制到第一个输入错误

    我正在尝试绘制来自不断写入 CSV 文件的传感器的数据 虽然成功创建实时绘图 但每个新数据条目都会创建一条延伸到第一个数据条目的附加线 见下文 Python 3 4 脚本 import matplotlib pyplot as plt im
  • 处理大文件的最快方法?

    我有多个 3 GB 制表符分隔文件 每个文件中有 2000 万行 所有行都必须独立处理 任何两行之间没有关系 我的问题是 什么会更快 逐行阅读 with open as infile for line in infile 将文件分块读入内存
  • 如何在 robobrowser-python 中发出 POST 请求

    http robobrowser readthedocs org en latest api html http robobrowser readthedocs org en latest api html 我正在尝试使用 APIbrows
  • 如何循环遍历字典列表并打印特定键的值?

    我是 Python 新手 有一个问题 我知道这是一个非常简单的问题 运行Python 3 4 我有一个需要迭代并提取特定信息的列表 以下是列表 称为部分 的示例 已截断 数千个项目 state DEAD id phwl type name
  • 使用 urllib 编码时保持 url 参数有序

    我正在尝试用 python 模拟 get 请求 我有一个参数字典 并使用 urllib urlencode 对它们进行 urlencode 我注意到虽然字典的形式是 k1 v1 k2 v2 k3 v3 urlencoding 后参数的顺序切

随机推荐