Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中绘制双方框图(2轴方框图;方框图关联图)_Python_Matplotlib - Fatal编程技术网

在Python中绘制双方框图(2轴方框图;方框图关联图)

在Python中绘制双方框图(2轴方框图;方框图关联图),python,matplotlib,Python,Matplotlib,我想用x轴和y轴上的方框图来绘制两个变量的分布。我想要得到的图表的例子可以在这里找到,但是他们使用的是R 我想知道是否有可能在Python中以matlplotlib.pyplot为例获得相同的结果。boxplot函数似乎不适用于这种图表 我为两组人做了类似的尝试: import matplotlib.pyplot as plt x1 = [x11, x12, ..., x1n] x2 = [x21, x22, ..., x2n] y1 = [y11, y12, ..., y1n] y2 = [y

我想用x轴和y轴上的方框图来绘制两个变量的分布。我想要得到的图表的例子可以在这里找到,但是他们使用的是R

我想知道是否有可能在Python中以
matlplotlib.pyplot
为例获得相同的结果。
boxplot
函数似乎不适用于这种图表

我为两组人做了类似的尝试:

import matplotlib.pyplot as plt
x1 = [x11, x12, ..., x1n]
x2 = [x21, x22, ..., x2n]
y1 = [y11, y12, ..., y1n]
y2 = [y21, y22, ..., y2n]

data = [list(zip(x1,y1)), list(zip(x2,y2))]
fig, ax = plt.subplots()
ax.boxplot(data)
结果如下:
以下是使用
numpys
百分位数法和
矩形
s和
Line2D
s进行实际绘图时解决问题的粗略尝试:

from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.lines import Line2D

import numpy as np

def boxplot_2d(x,y, ax, whis=1.5):
    xlimits = [np.percentile(x, q) for q in (25, 50, 75)]
    ylimits = [np.percentile(y, q) for q in (25, 50, 75)]

    ##the box
    box = Rectangle(
        (xlimits[0],ylimits[0]),
        (xlimits[2]-xlimits[0]),
        (ylimits[2]-ylimits[0]),
        ec = 'k',
        zorder=0
    )
    ax.add_patch(box)

    ##the x median
    vline = Line2D(
        [xlimits[1],xlimits[1]],[ylimits[0],ylimits[2]],
        color='k',
        zorder=1
    )
    ax.add_line(vline)

    ##the y median
    hline = Line2D(
        [xlimits[0],xlimits[2]],[ylimits[1],ylimits[1]],
        color='k',
        zorder=1
    )
    ax.add_line(hline)

    ##the central point
    ax.plot([xlimits[1]],[ylimits[1]], color='k', marker='o')

    ##the x-whisker
    ##defined as in matplotlib boxplot:
    ##As a float, determines the reach of the whiskers to the beyond the
    ##first and third quartiles. In other words, where IQR is the
    ##interquartile range (Q3-Q1), the upper whisker will extend to
    ##last datum less than Q3 + whis*IQR). Similarly, the lower whisker
    ####will extend to the first datum greater than Q1 - whis*IQR. Beyond
    ##the whiskers, data are considered outliers and are plotted as
    ##individual points. Set this to an unreasonably high value to force
    ##the whiskers to show the min and max values. Alternatively, set this
    ##to an ascending sequence of percentile (e.g., [5, 95]) to set the
    ##whiskers at specific percentiles of the data. Finally, whis can
    ##be the string 'range' to force the whiskers to the min and max of
    ##the data.
    iqr = xlimits[2]-xlimits[0]

    ##left
    left = np.min(x[x > xlimits[0]-whis*iqr])
    whisker_line = Line2D(
        [left, xlimits[0]], [ylimits[1],ylimits[1]],
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_line)
    whisker_bar = Line2D(
        [left, left], [ylimits[0],ylimits[2]],
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_bar)

    ##right
    right = np.max(x[x < xlimits[2]+whis*iqr])
    whisker_line = Line2D(
        [right, xlimits[2]], [ylimits[1],ylimits[1]],
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_line)
    whisker_bar = Line2D(
        [right, right], [ylimits[0],ylimits[2]],
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_bar)

    ##the y-whisker
    iqr = ylimits[2]-ylimits[0]

    ##bottom
    bottom = np.min(y[y > ylimits[0]-whis*iqr])
    whisker_line = Line2D(
        [xlimits[1],xlimits[1]], [bottom, ylimits[0]], 
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_line)
    whisker_bar = Line2D(
        [xlimits[0],xlimits[2]], [bottom, bottom], 
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_bar)

    ##top
    top = np.max(y[y < ylimits[2]+whis*iqr])
    whisker_line = Line2D(
        [xlimits[1],xlimits[1]], [top, ylimits[2]], 
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_line)
    whisker_bar = Line2D(
        [xlimits[0],xlimits[2]], [top, top], 
        color = 'k',
        zorder = 1
    )
    ax.add_line(whisker_bar)

    ##outliers
    mask = (x<left)|(x>right)|(y<bottom)|(y>top)
    ax.scatter(
        x[mask],y[mask],
        facecolors='none', edgecolors='k'
    )

#the figure and axes
fig,(ax1,ax2) = plt.subplots(ncols=2)

#some fake data
x = np.random.rand(1000)**2
y = np.sqrt(np.random.rand(1000))
#x = np.random.rand(1000)
#y = np.random.rand(1000)

#plotting the original data
ax1.scatter(x,y,c='r', s=1)

#doing the box plot
boxplot_2d(x,y,ax=ax2, whis=1)

plt.show()
从matplotlib导入pyplot作为plt
从matplotlib.patches导入矩形
从matplotlib.lines导入Line2D
将numpy作为np导入
def箱线图_2d(x,y,ax,whis=1.5):
xlimits=[np.百分位数(x,q)表示(25,50,75)]
ylimits=[np.百分位(y,q)表示(25,50,75)]
##盒子
长方形(
(xlimits[0],ylimits[0]),
(xlimits[2]-xlimits[0]),
(ylimits[2]-ylimits[0]),
ec='k',
zorder=0
)
ax.添加补丁(框)
##x中位数
vline=Line2D(
[xlimits[1],xlimits[1],[ylimits[0],ylimits[2],
color='k',
佐德=1
)
ax.添加线(V线)
##y中位数
hline=Line2D(
[xlimits[0],xlimits[2],[ylimits[1],ylimits[1],
color='k',
佐德=1
)
ax.add_行(hline)
##中心点
ax.plot([xlimits[1]],[ylimits[1]],color='k',marker='o')
##x须
##在matplotlib boxplot中定义:
##作为一个浮子,它决定了触须到达的范围
##第一和第三个四分位数。换句话说,其中IQR是
##四分位区间(Q3-Q1),上部晶须将延伸至
##最后一个数据小于Q3+whis*IQR)。同样,下须
####将延伸至大于Q1的第一个基准面-whis*IQR。超过
##晶须、数据被视为异常值,并绘制为
##个人观点。将此设置为不合理的高值以强制执行
##显示最小值和最大值的胡须。或者,设置此选项
##以百分位数的升序(例如[5,95])设置
##在数据的特定百分位上的胡须。最后,我们可以
##是字符串“范围”,以强制胡须达到最小值和最大值
##数据。
iqr=xlimits[2]-xlimits[0]
##左
左=np.min(x[x>xlimits[0]-whis*iqr])
晶须线=线2D(
[左,xlimits[0],[ylimits[1],ylimits[1],
颜色='k',
佐德=1
)
ax.添加线(胡须线)
晶须条=线2D(
[左,左],[ylimits[0],ylimits[2]],
颜色='k',
佐德=1
)
ax.添加线(须条)
##对
右=np.max(x[xylimits[0]-whis*iqr])
晶须线=线2D(
[xlimits[1],xlimits[1],[bottom,ylimits[0],
颜色='k',
佐德=1
)
ax.添加线(胡须线)
晶须条=线2D(
[xlimits[0],xlimits[2],[bottom,bottom],
颜色='k',
佐德=1
)
ax.添加线(须条)
##顶
top=np.max(y[y
当然,通过允许关键字参数,可以将这些参数转发到
矩形
Line2D
调用,这仍然可以做得更好。最终结果如下所示:


左侧以散点图的形式显示实际数据,右侧显示生成的二维方框图。希望这能有所帮助。

我建议您考虑绘制彩色散点图,而不是二维箱线图。其中一些例子很难非常清楚地说明任何事情。我不完全确定如何在matplotlib中实现这一点(但我非常确定),但真正的问题是为什么?使用当前的
boxplot
实现无法获得预期的结果,您必须编写自己的实现。如果可以计算
x
y
尺寸的第一个和第三个,则可以使用适当的coordinates@Andrew我需要一张科学文章中的图表。彩色散点图是在初衷中制作的,但我们相信,通过双箱线图将更容易可视化我们想要显示的信息@DizietAsahi我要试试,谢谢你使用
矩形的提示。如果我成功了,我会尝试一些东西并发布一个答案。我希望你是对的。如果这些例子有什么值得参考的话,我想我很难从这些例子中看出任何不可能是我的意义