我写这篇文章是为了在用散点图绘制圆时有一个参考帖子,但用户想要提供分散圆的真实半径,而不是抽象的大小.

我一直在四处寻找,还有其他帖子解释了它的原理,但还没有遇到现成的功能.我已经试过了,希望我已经接近找到解决方案.

这就是我到目前为止所拥有的:

import matplotlib.pyplot as plt
import numpy as np

def true_scatter(x, y, r, ax, **kwargs):
    # Should work for an equal aspect axis
    ax.set_aspect('equal')
    
    # Access the DPI and figure size
    dpi = ax.figure.dpi
    fig_width_inch, _ = ax.figure.get_size_inches()

    # Calculate plot size in data units
    xlim = ax.get_xlim()
    plot_width_data_units = xlim[1] - xlim[0]

    # Calculate the scale factor: pixels per data unit
    plot_width_pixels = fig_width_inch * dpi
    scale = plot_width_pixels / plot_width_data_units

    # Convert radius to pixels, then area to points squared
    radius_pixels = r * scale
    area_pixels_squared = np.pi * (radius_pixels ** 2)
    area_points_squared = area_pixels_squared * (72 / dpi) ** 2

    # Scatter plot with converted area
    scatter = ax.scatter(x, y, s=area_points_squared, **kwargs)
    return scatter

# Example with single scatter
fig, ax = plt.subplots()
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
scatter = true_scatter(0, 0, 1, ax)
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
plt.grid()
plt.show()

Wrong single scatter plot

不幸的是,这并不完全是答案.我得到一个半径为~1.55的圆,而不是1. 有没有人能发现我的方法有什么问题?

谢谢!

推荐答案

现在还不太清楚你想让r作为圆的半径还是直径.下面的代码假设它是半径(如果您想要直径,只需省略* 2.

有关如何测量网点大小的讨论,请参见this post.

下面的代码将以数据为单位的半径转换为像素,然后转换为"点".测试了三种不同的尺寸.

import matplotlib.pyplot as plt

def true_scatter(x, y, r, ax, **kwargs):
    # the radius is given in data coordinates in the x direction
    # Should work for an equal aspect axis
    ax.set_aspect('equal')

    # measure the data coordinates in pixels
    radius_in_pixels, _ = ax.transData.transform((r, 0)) - ax.transData.transform((0, 0))
    # one "point" is 1/72 of an inch
    radius_in_points = radius_in_pixels * 72.0 / ax.figure.dpi
    # the scatter plot size is set in square point units
    area_points_squared = (radius_in_points * 2) ** 2

    # Scatter plot with converted area
    scatter = ax.scatter(x, y, s=area_points_squared, **kwargs)
    return scatter

# Example with three scatter dots with different radii
fig, ax = plt.subplots(figsize=(5, 5))
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
scatter = true_scatter(0, 0, 1.5, ax)
scatter = true_scatter(0, 0, 1, ax)
scatter = true_scatter(0, 0, 0.5, ax)
ax.grid()
plt.show()

scatter plot with radius in data units

Python相关问答推荐

Locust请求中的Python和参数

更改matplotlib彩色条的字体并勾选标签?

对Numpy函数进行载体化

Pandas 在最近的日期合并,考虑到破产

OR—Tools CP SAT条件约束

递归访问嵌套字典中的元素值

如何在表中添加重复的列?

如何在Python中找到线性依赖mod 2

什么是最好的方法来切割一个相框到一个面具的第一个实例?

Python中的变量每次增加超过1

从Windows Python脚本在WSL上运行Linux应用程序

可以bcrypts AES—256 GCM加密损坏ZIP文件吗?

处理具有多个独立头的CSV文件

Scipy差分进化:如何传递矩阵作为参数进行优化?

对于标准的原始类型注释,从键入`和`从www.example.com `?

替换包含Python DataFrame中的值的<;

使用xlsxWriter在EXCEL中为数据帧的各行上色

try 在单个WITH_COLUMNS_SEQ操作中链接表达式时,使用Polars数据帧时出现ComputeError

Pandas:根据相邻行之间的差异过滤数据帧

生产者/消费者-Queue.get by list