使用matplotlib在范围之间打印点

2024-05-06 00:46:42 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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])....}

enter image description here

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

我当前的代码如下所示:

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)

有没有更好的办法


Tags: andtheinimportforrangebetweenax
1条回答
网友
1楼 · 发布于 2024-05-06 00:46:42

一些评论:

  • 可以使用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)

example plot

相关问题 更多 >