如何在保持所有条形之间均匀间距的情况下更改条形的宽度

huangapple go评论81阅读模式
英文:

How to change the bar width while keeping an even space around all bars

问题

我正在尝试使用pandas制作一个条形图,在所有条形周围有均等的间距。当我不指定width时,这在默认情况下可以正常工作。问题是,当我指定width时,图表左右两侧的边距不会改变,这使得最左边和最右边的条之间的间距比其他的要大。我尝试使用ax.margins(x=0)来调整边距,但没有效果。如何确保所有条形的间距均匀?

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

matplotlib.use('TkAgg')

print(matplotlib.__version__)  # 3.5.3
print(pd.__version__)  # 1.3.5


def grid_in_between(ax):
    """Create gridlines in between (major) data axis values using minor gridlines

    Args:
        ax: Matplotlib axes
    """
    ticks = ax.get_xticks()
    ax.set_xticks(np.array(ticks[:-1]) + np.diff(ticks) / 2, minor=True)
    ax.grid(visible=True, axis='x', which='minor')
    ax.grid(visible=False, axis='x', which='major')
    ax.tick_params(which='minor', length=0, axis='x')


df = pd.DataFrame({'value': range(8)})

fig, ax = plt.subplots(1, 2)
df.plot.bar(ax=ax[0])
df.plot.bar(ax=ax[1], width=.95)
grid_in_between(ax[0])
grid_in_between(ax[1])
ax[0].set_title('Evenly spaced')
ax[1].set_title('Parameter width\nmakes first and last space bigger')
ax[1].margins(x=0)  # no effect
plt.show()

如何在保持所有条形之间均匀间距的情况下更改条形的宽度



<details>
<summary>英文:</summary>

I&#39;m trying to make a bar chart where there is equal space around all bars using `pandas`. When I don&#39;t specify a `width` this works fine out of the box. The problem is that when I specify the `width`, the margin on the left and right of the chart doesn&#39;t change, which makes the space around the left-most and right-most bar bigger than for the others. I&#39;ve tried adjusting the margin with `ax.margins(x=0)` but this has no effect. How can I keep an even space for all bars?

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

matplotlib.use(&#39;TkAgg&#39;)

print(matplotlib.__version__)  # 3.5.3
print(pd.__version__)  # 1.3.5


def grid_in_between(ax):
    &quot;&quot;&quot;Create gridlines in between (major) data axis values using minor gridlines

    Args:
        ax: Matplotlib axes
    &quot;&quot;&quot;
    ticks = ax.get_xticks()
    ax.set_xticks(np.array(ticks[:-1]) + np.diff(ticks) / 2, minor=True)
    ax.grid(visible=True, axis=&#39;x&#39;, which=&#39;minor&#39;)
    ax.grid(visible=False, axis=&#39;x&#39;, which=&#39;major&#39;)
    ax.tick_params(which=&#39;minor&#39;, length=0, axis=&#39;x&#39;)


df = pd.DataFrame({&#39;value&#39;: range(8)})

fig, ax = plt.subplots(1, 2)
df.plot.bar(ax=ax[0])
df.plot.bar(ax=ax[1], width=.95)
grid_in_between(ax[0])
grid_in_between(ax[1])
ax[0].set_title(&#39;Evenly spaced&#39;)
ax[1].set_title(&#39;Parameter width\nmakes first and last space bigger&#39;)
ax[1].margins(x=0)  # no effect
plt.show()

如何在保持所有条形之间均匀间距的情况下更改条形的宽度

答案1

得分: 1

设置x轴限制以校正宽度:

barwidth = 0.95
df.plot.bar(ax=ax[1], width=barwidth)
.
.
.
# 设置x轴限制
ax[1].set_xlim(
    df.index.min() - barwidth/2 - (1 - barwidth) / 2,
    df.index.max() + barwidth/2 + (1 - barwidth) / 2
)
英文:

Setting the x axis limits to correct for the width:

如何在保持所有条形之间均匀间距的情况下更改条形的宽度

barwidth = 0.95
df.plot.bar(ax=ax[1], width=barwidth)
.
.
.
#Set the x axis limits
ax[1].set_xlim(
    df.index.min() - barwidth/2 - (1 - barwidth) / 2,
    df.index.max() + barwidth/2 + (1 - barwidth) / 2
)

答案2

得分: 1

你确实应该设置X轴的限制,但不要太复杂,只需取最小/最大刻度值,再分别减去和加上0.5。

让我们将这行代码添加到grid_in_between函数的最后一行:

def grid_in_between(ax):
    """在(主要)数据轴数值之间创建网格线,使用次要网格线
    Args:
        ax: Matplotlib axes
    """
    ticks = ax.get_xticks()
    ax.set_xticks(np.array(ticks[:-1]) + np.diff(ticks) / 2, minor=True)
    ax.grid(visible=True, axis='x', which='minor')
    ax.grid(visible=False, axis='x', which='major')
    ax.tick_params(which='minor', length=0, axis='x')
    ax.set_xlim(min(ticks)-0.5, max(ticks)+0.5)

输出:

如何在保持所有条形之间均匀间距的情况下更改条形的宽度

英文:

You should indeed set the X-axis limits, but nothing fancy, just take the min/max ticks -/+ 0.5.

Let's add this as last line to the grid_in_between function:

def grid_in_between(ax):
    &quot;&quot;&quot;Create gridlines in between (major) data axis values using minor gridlines
    Args:
        ax: Matplotlib axes
    &quot;&quot;&quot;
    ticks = ax.get_xticks()
    ax.set_xticks(np.array(ticks[:-1]) + np.diff(ticks) / 2, minor=True)
    ax.grid(visible=True, axis=&#39;x&#39;, which=&#39;minor&#39;)
    ax.grid(visible=False, axis=&#39;x&#39;, which=&#39;major&#39;)
    ax.tick_params(which=&#39;minor&#39;, length=0, axis=&#39;x&#39;)
    ax.set_xlim(min(ticks)-0.5, max(ticks)+0.5)

Output:

如何在保持所有条形之间均匀间距的情况下更改条形的宽度

huangapple
  • 本文由 发表于 2023年8月4日 03:20:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76831055.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定