python左右同时对齐_python – 左右对齐matplotlib散点图标记

我正在使用matplotlib scatterplot函数在垂直线上创建句柄的外观以描绘图形的某些部分.但是,为了使它们看起来正确,我需要能够将散点图标记对齐到左边(对于左边的线/描绘边)和/或右(对于右边的线/描边器).

这是一个例子:

#create the figure

fig = plt.figure(facecolor = '#f3f3f3', figsize = (11.5, 6))

ax = plt. ax = plt.subplot2grid((1, 1), (0,0))

#make some random data

index = pandas.DatetimeIndex(start = '01/01/2000', freq = 'b', periods = 100)

rand_levels = pandas.DataFrame( numpy.random.randn(100, 4)/252., index = index, columns = ['a', 'b', 'c', 'd'])

rand_levels = 100*numpy.exp(rand_levels.cumsum(axis = 0))

ax.stackplot(rand_levels.index, rand_levels.transpose())

#create the place holder for the vertical lines

d1, d2 = index[25], index[50]

#draw the lines

ymin, ymax = ax.get_ylim()

ax.vlines([index[25], index[50]], ymin = ymin, ymax = ymax, color = '#353535', lw = 2)

#draw the markers

ax.scatter(d1, ymax, clip_on = False, color = '#353535', marker = '>', s = 200, zorder = 3)

ax.scatter(d2, ymax, clip_on = False, color = '#353535', marker = '<', s = 200, zorder = 3)

#reset the limits

ax.set_ylim(ymin, ymax)

ax.set_xlim(rand_levels.index[0], rand_levels.index[-1])

plt.show()

上面的代码几乎给了我正在寻找的图形,如下所示:

但是,我希望最左边的标记(“>”)“向左对齐”(即略微向右移动),以便该行继续到标记的背面同样地,我想要最右边的标记(“<”)“向右对齐”(即略微向左移动).像这样:

有关如何以灵活方式完成此任务的任何指导或建议?

注意:实际上,我的DataFrame索引是pandas.Datetime而不是整数,正如我为这个简单的例子所提供的那样.

解决方法:

我喜欢这个问题,对我的第一个答案不满意.特别是,为了对齐标记,创建图形特定对象(mark_align_ *)似乎是不必要的麻烦.我最终发现的是通过verts指定标记的功能(2元素浮点数列表,或Nx2数组,指定相对于目标绘图点的标记顶点(0,0)).为了这个目的利用这个功能,我写了这个函数,

from matplotlib import markers

from matplotlib.path import Path

def align_marker(marker, halign='center', valign='middle',):

"""

create markers with specified alignment.

Parameters

----------

marker : a valid marker specification.

See mpl.markers

halign : string, float {'left', 'center', 'right'}

Specifies the horizontal alignment of the marker. *float* values

specify the alignment in units of the markersize/2 (0 is 'center',

-1 is 'right', 1 is 'left').

valign : string, float {'top', 'middle', 'bottom'}

Specifies the vertical alignment of the marker. *float* values

specify the alignment in units of the markersize/2 (0 is 'middle',

-1 is 'top', 1 is 'bottom').

Returns

-------

marker_array : numpy.ndarray

A Nx2 array that specifies the marker path relative to the

plot target point at (0, 0).

Notes

-----

The mark_array can be passed directly to ax.plot and ax.scatter, e.g.::

ax.plot(1, 1, marker=align_marker('>', 'left'))

"""

if isinstance(halign, (str, unicode)):

halign = {'right': -1.,

'middle': 0.,

'center': 0.,

'left': 1.,

}[halign]

if isinstance(valign, (str, unicode)):

valign = {'top': -1.,

'middle': 0.,

'center': 0.,

'bottom': 1.,

}[valign]

# Define the base marker

bm = markers.MarkerStyle(marker)

# Get the marker path and apply the marker transform to get the

# actual marker vertices (they should all be in a unit-square

# centered at (0, 0))

m_arr = bm.get_path().transformed(bm.get_transform()).vertices

# Shift the marker vertices for the specified alignment.

m_arr[:, 0] += halign / 2

m_arr[:, 1] += valign / 2

return Path(m_arr, bm.get_path().codes)

使用此功能,可以将所需的标记绘制为,

ax.plot(d1, 1, marker=align_marker('>', halign='left'), ms=20,

clip_on=False, color='k', transform=ax.get_xaxis_transform())

ax.plot(d2, 1, marker=align_marker('<', halign='right'), ms=20,

clip_on=False, color='k', transform=ax.get_xaxis_transform())

或者使用ax.scatter,

ax.scatter(d1, 1, 200, marker=align_marker('>', halign='left'),

clip_on=False, color='k', transform=ax.get_xaxis_transform())

ax.scatter(d2, 1, 200, marker=align_marker('<', halign='right'),

clip_on=False, color='k', transform=ax.get_xaxis_transform())

在这两个示例中,我都指定了transform = ax.get_xaxis_transform(),以便标记的垂直位置在轴坐标(1是轴的顶部),这与标记对齐无关.

与我之前的解决方案相比,此解决方案的明显优势在于它不需要了解标记大小,绘图函数(ax.plot与ax.scatter)或轴(用于转换)的知识.相反,只需指定一个标记及其对齐!

干杯!

标签:python,matplotlib,scatter-plot

来源: https://codeday.me/bug/20190612/1224182.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值