【问题标题】:Plotting points between ranges using matplotlib使用 matplotlib 在范围之间绘制点
【发布时间】:2021-04-25 13:02:06
【问题描述】:

我正在尝试在范围之间绘制点,但由于我缺乏绘图库知识,因此效果不佳。如果您查看下图,有时我的数据显示在矩形之外,即范围。我的数据格式如下:

d = {(x, y, [values between x and y]), (x, y, [values between x and y]) ....}
d = {(10, 15, [1, 4, 4, 4, 4, 4]), (20, 25, [4, 5, 5, 5, 5, 5])....}

蓝色点是范围之间的值,矩形是范围以及作为参考线的虚线。

我当前的代码如下所示:

from random import randint
from random import randrange, uniform
import numpy as np
from matplotlib.path import Path
import matplotlib.patches as patches
import matplotlib.pyplot as plt
 
def plotResults(d, referenceLine):
    ''' d is of type {(x, y, [values between x and y]), (x, y, [values between x and y])}'''
    #remap (x, y) points to start from 0 
    gap = 10
    start, end = 0, 0
    remap = []
    maxValue = 0
    for k, val in d.items():
        x, y = k
        start = end + gap
        end = start + (y - x)
        maxValue = end * 2
        remap.append((start, end, val))
 
    #draw the vertical rectangles
    vertices = []
    codes = []
    prev = 0
    for i in range(len(remap)):
        codes += [Path.MOVETO] + [Path.LINETO]*3
        vertices += [(remap[i][0]+prev, 0), (remap[i][0]+prev, 8), (remap[i][1]+prev, 8), (remap[i][1]+prev, 0)]
        prev = remap[i][1] + gap
    path = Path(vertices, codes)
    pathpatch = patches.PathPatch(path, facecolor='None', edgecolor='green')
    fig, ax = plt.subplots()
 
    #draw the points inside the rectangles
    for i in range(len(remap)):
        p = 0
        for j in range(remap[i][1]-remap[i][0]):
            mm = remap[i][2]
            circ = plt.Circle((remap[i][0]+j + prev, mm[p]), 0.1, color='b', alpha=0.3)
            ax.add_patch(circ)
            p += 1
        prev = remap[i][1] + gap
 
    #draw the referenceLine
    x = np.linspace(0, maxValue, 500)
    y = [referenceLine for i in range(len(x))]
    line1, = ax.plot(x, y, '--', linewidth=0.5)
    ax.add_patch(pathpatch)
    ax.autoscale_view()
    plt.show()
 
#generate the dataset of ranges with the values inside those ranges
referenceLine = 4
d = {}
start, end, gap = 0, 0, 10
for i in range(10):
    duration = randrange(40, 60)
    start = end + gap
    end = start + duration
    d[(start, end)] = [randint(0, 7) for j in range(end-start)]
    print(start, end)
plotResults(d, referenceLine)

有没有更好的方法来做到这一点?

【问题讨论】:

  • 您不需要构建该 Patch 对象。使用 ax.plot 并为其提供 x 和 y 值数组

标签: python matplotlib


【解决方案1】:

一些备注:

  • 矩形的线条可以直接使用plot([x0,x0,x1,x1],[y0,y1,y1,y0])绘制。
  • matplotlib 中的圆的宽度与高度相同,但以轴的坐标测量。由于 x 轴比 y 轴宽得多,所以圆会收缩成一条线。 Matplotlib 的scatter() 可以在图像上绘制圆点
  • 原始代码中存在一个错误:prev 在第三个for 循环中没有被初始化。这使得第一个矩形的圆向 x 轴的中心移动。
  • 列表remap 看起来很混乱,似乎包含与字典相同的信息。代码可以大大简化,省略。

函数的小改写如下所示:

def plotResults(d, referenceLine):
    ''' d is of type {(x, y, [values between x and y]), (x, y, [values between x and y])}'''

    fig, ax = plt.subplots()
    # draw the vertical rectangles
    prev = 0
    for (start, end), value in d.items():
        ax.plot([start + prev, start + prev, end + prev, end + prev], [0, 8, 8, 0], color='green')
        prev = end + gap

    # draw the points inside the rectangles
    prev = 0
    for (start, end), values in d.items():
        for j in range(end - start):
            ax.scatter(start + j + prev, values[j], marker='o', color='blue') # marker='|' for a vertical line
        prev = end + gap

    # draw the referenceLine
    ax.axhline(referenceLine, linestyle='--', linewidth=0.5)
    plt.show()

plotResults的代码中使用prev使得差距比10大得多。此外,startend 值被移动到它们 x 值的两倍左右。目前尚不清楚这是否是有意的。一个更简化的代码,startend 保持它们的位置,可能看起来像:

from random import randint, randrange
import matplotlib.pyplot as plt

def plotResults(d, referenceLine):
    ''' d is of type {(x, y, [values between x and y]), (x, y, [values between x and y])}'''
    fig, ax = plt.subplots()
    # draw the vertical rectangles
    for (start, end), value in d.items():
        ax.plot([start - 0.5, start - 0.5, end - 0.5, end - 0.5], [0, 7.1, 7.1, 0], color='green')

    # draw the points inside the rectangles
    for (start, end), values in d.items():
        ax.scatter(range(start, end), values, marker='|', color='blue')
    # draw the referenceLine
    ax.axhline(referenceLine, linestyle='--', linewidth=0.5)
    plt.show()

# generate the dataset of ranges with the values inside those ranges
referenceLine = 4
d = {}
start, end, gap = 0, 0, 10
# for i in range(10):
for i in range(10):
    duration = randrange(40, 60)
    start = end + gap
    end = start + duration
    d[(start, end)] = [randint(0, 7) for j in range(end - start)]
    print(start, end)
plotResults(d, referenceLine)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    相关资源
    最近更新 更多