【问题标题】:Broken axis slash marks inside bar chart in matplotlib?matplotlib中条形图中的断轴斜线标记?
【发布时间】:2019-05-07 15:29:59
【问题描述】:

我见过 matplotlib 将断轴斜线标记放置在轴上的示例,例如 this one

我的问题,我怎样才能把它放在栏杆坏了的地方?这可以以编程方式完成,以逐月更新时间序列图吗?

下面是我想要使用 excel 完成的示例。请注意巴黎六月酒吧和马德里五月酒吧中的波浪号。波浪线隐藏了它所覆盖的栏的一部分。

我还提供了更简单的示例数据以及到目前为止我能够做到的事情。

XX = pd.Series([200,400,100,1400],index=['x1','x2','x3','x4'])
fig, (ax1,ax2) = plt.subplots(2,1,sharex=True,
                         figsize=(5,6))
ax1.spines['bottom'].set_visible(False)
ax1.tick_params(axis='x',which='both',bottom=False)
ax2.spines['top'].set_visible(False)
ax2.set_ylim(0,500)
ax1.set_ylim(1200,1500)
ax1.set_yticks(np.arange(1000,1501,100))
XX.plot(ax=ax1,kind='bar')
XX.plot(ax=ax2,kind='bar')
for tick in ax2.get_xticklabels():
    tick.set_rotation(0)
d = .015  
kwargs = dict(transform=ax1.transAxes, color='k', clip_on=False)
ax1.plot((-d, +d), (-d, +d), **kwargs)      
ax1.plot((1 - d, 1 + d), (-d, +d), **kwargs)
kwargs.update(transform=ax2.transAxes)  
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs)
plt.show()

【问题讨论】:

  • 到底是什么问题?链接问题中的答案显示了如何(以编程方式)执行此操作。是不是你想要一个波浪符号而不是直线?
  • 链接答案中的符号仅在轴上。我共享的 Excel 图像在轴和条上都有它。如何将斜杠或波浪线放在条形本身上
  • 您可以将它们放置在条形大于下图限制(在本例中为 8M)的每个位置。
  • 您能否提供代码,说明如何对我刚刚提供的示例数据执行此操作?当我尝试在 x4 条上添加斜线时,由于我设置的 ylimit,它被隐藏了。

标签: python matplotlib bar-chart


【解决方案1】:

只是为了说明原理,你可以在每一个条形超过下轴上限的位置,也可以在一个条超过上轴下限的位置放置相同的线。

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

XX = pd.Series([200,400,100,1400],index=['x1','x2','x3','x4'])
fig, (ax1,ax2) = plt.subplots(2,1,sharex=True,
                         figsize=(5,6))
ax1.spines['bottom'].set_visible(False)
ax1.tick_params(axis='x',which='both',bottom=False)
ax2.spines['top'].set_visible(False)

bs = 500
ts = 1000

ax2.set_ylim(0,bs)
ax1.set_ylim(ts,1500)
ax1.set_yticks(np.arange(1000,1501,100))

bars1 = ax1.bar(XX.index, XX.values)
bars2 = ax2.bar(XX.index, XX.values)

for tick in ax2.get_xticklabels():
    tick.set_rotation(0)
d = .015  
kwargs = dict(transform=ax1.transAxes, color='k', clip_on=False)
ax1.plot((-d, +d), (-d, +d), **kwargs)      
ax1.plot((1 - d, 1 + d), (-d, +d), **kwargs)
kwargs.update(transform=ax2.transAxes)  
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs)

for b1, b2 in zip(bars1, bars2):
    posx = b2.get_x() + b2.get_width()/2.
    if b2.get_height() > bs:
        ax2.plot((posx-3*d, posx+3*d), (1 - d, 1 + d), color='k', clip_on=False,
                 transform=ax2.get_xaxis_transform())
    if b1.get_height() > ts:
        ax1.plot((posx-3*d, posx+3*d), (- d, + d), color='k', clip_on=False,
                 transform=ax1.get_xaxis_transform())
plt.show()

它看起来不太好,但当然可以适应更好的形状。

【讨论】:

  • 谢谢!我可以看到调整它以添加应该隐藏部分栏的空白
【解决方案2】:

前段时间我需要破坏 y 轴并创建了一些代码来实现它。现在,我已经将它提交给PyPi,以便其他人可以使用它。不过,它远不是最终版本。欢迎任何 cmets,还有GitHub project,当然任何人都可以在其中进行协作。欢迎任何问题、代码和其他任何内容。

另外,请考虑阅读以下帖子。在决定是否使用之前,它给出了一些很好的理由说明为什么不希望使用损坏的 y 轴。我认为的主要观点之一是打破 y 轴会使比例感完全消失。由于 y 轴范围有限,因此看到这样的图可能会相当混乱。也就是说,如果使用,我建议让观众了解使用这种情节可能产生的奇怪比例。

安装:

pip install plotinpy

以下是损坏的 y 轴的一些示例用法:

示例

简单的断条

plt.figure()
pnp.plot_bars_with_breaks(
    [1, 2, 30],
    [(15, 25)]
    )
plt.savefig("img/example1.png")

风格的断条

plt.figure()
pnp.plot_bars_with_breaks(
    [1, 2, 30, 1000],
    [(15, 25), (50, 975)],
    style="~~",
    break_args={"hatch": '///'}
    )
plt.savefig("img/example2.png")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多