如何在柱状图中将柱子居中,当其中一个柱子的数值为无值时

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

how to center bars on a bar chart when one of the bars is none valued

问题

问题是其中一个条形图不居中,因为技术上它旁边的条形图(实际上没有)可能在某种程度上干扰了,或者可能没有,我不知道。

我的代码如下:

import matplotlib.pyplot as plt

# 定义数据
categories = ['bear', 'neutral', 'man']
wins = [2, 3, 7]
attacks = [3, None, 5]

# 创建条形图
fig, ax = plt.subplots()

ax.bar(categories, wins, 0.35, label='Win')
ax.bar([i + 0.35 for i in range(len(attacks)) if attacks[i] is not None],
       list(filter(None, attacks)), 0.35, label='Attack')

# 添加标签和图例
ax.set_xticks([i + 0.35/2 for i in range(len(categories)])
ax.legend()

# 显示图表
plt.show()

问题在于这会生成这个图表:
如何在柱状图中将柱子居中,当其中一个柱子的数值为无值时

这是我想要的(中间的条形图在这张图片中居中):
如何在柱状图中将柱子居中,当其中一个柱子的数值为无值时

英文:

My problem is that one of the bars is not centered as the bar that is probably next to it technically (it is none) is somehow interfering or maybe not i don't know.

my code is:

import matplotlib.pyplot as plt

# Define the data
categories = ['bear', 'neutral', 'man']
wins = [2, 3, 7]
attacks = [3, None, 5]

# Create a bar chart
fig, ax = plt.subplots()

ax.bar(categories, wins, 0.35, label='Win')
ax.bar([i + 0.35 for i in range(len(attacks)) if attacks[i] is not None],
                list(filter(None, attacks)), 0.35, label='Attack')

# Add labels and legend
ax.set_xticks([i + 0.35/2 for i in range(len(categories))])
ax.legend()

# Display the chart
plt.show()

the problem is that this makes this chart:
如何在柱状图中将柱子居中,当其中一个柱子的数值为无值时

this is what i want (the middle bar is centered in this picture):
如何在柱状图中将柱子居中,当其中一个柱子的数值为无值时

答案1

得分: 1

以下是您要翻译的代码部分:

import matplotlib.pyplot as plt

# Define the data
categories = ['bear', 'neutral', 'man']
wins = [2, 3, 7]
attacks = [3, None, 5]

# Create a bar chart
fig, ax = plt.subplots()

ax.bar([i + (0.35 / 2 if attacks[i] is None else 0) for i in range(len(attacks))],
       wins, 0.35, label='Win')
ax.bar([i + 0.35 for i in range(len(attacks)) if attacks[i] is not None],
       list(filter(None, attacks)), 0.35, label='Attack')

# Add labels and legend
ax.set_xticks([i + 0.35 / 2 for i in range(len(categories))], categories)
ax.legend()

# Display the chart
plt.show()
import matplotlib.pyplot as plt
import numpy as np

# Define the data
categories = ['bear', 'neutral', 'man']
wins = [2, 3, 7]
attacks = [3, None, 5]

# Create a bar chart
fig, ax = plt.subplots()

# convert to numpy arrays of type float, representing None with NaN
wins = np.array(wins, dtype=float)
attacks = np.array(attacks, dtype=float)

# positions for the ticks
pos = np.arange(len(categories))

# delta change on the ticks depending on a win or an attack being NaN
delta = np.where(np.isnan(wins) | np.isnan(attacks), 0, 0.35/2)

# draw the bars, once using -delta and once +delta for the positions
ax.bar(pos - delta, wins, 0.35, label='Win')
ax.bar(pos + delta, attacks, 0.35, label='Attack')

# Add labels and legend
ax.set_xticks(pos, categories)
ax.legend()

plt.show()

希望这对您有所帮助。如果您需要任何进一步的帮助,请随时告诉我。

英文:

The following approach isn't very general, but it would work for your case. The positions for the first bars are modified when there isn't a second bar. The tick labels are set at the same time as the tick positions.

import matplotlib.pyplot as plt

# Define the data
categories = ['bear', 'neutral', 'man']
wins = [2, 3, 7]
attacks = [3, None, 5]

# Create a bar chart
fig, ax = plt.subplots()

ax.bar([i + (0.35 / 2 if attacks[i] is None else 0) for i in range(len(attacks))],
       wins, 0.35, label='Win')
ax.bar([i + 0.35 for i in range(len(attacks)) if attacks[i] is not None],
       list(filter(None, attacks)), 0.35, label='Attack')

# Add labels and legend
ax.set_xticks([i + 0.35 / 2 for i in range(len(categories))], categories)
ax.legend()

# Display the chart
plt.show()

如何在柱状图中将柱子居中,当其中一个柱子的数值为无值时

Another idea would be working array operations on the positions using numpy. When the data is converted to numpy arrays, the float type will represent None as NaN.

import matplotlib.pyplot as plt
import numpy as np

# Define the data
categories = ['bear', 'neutral', 'man']
wins = [2, 3, 7]
attacks = [3, None, 5]

# Create a bar chart
fig, ax = plt.subplots()

# convert to numpy arrays of type float, representing None with NaN
wins = np.array(wins, dtype=float)
attacks = np.array(attacks, dtype=float)

# positions for the ticks
pos = np.arange(len(categories))

# delta change on the ticks depending on a win or an attack being NaN
delta = np.where(np.isnan(wins) | np.isnan(attacks), 0, 0.35/2)

# draw the bars, once using -delta and once +delta for the positions
ax.bar(pos - delta, wins, 0.35, label='Win')
ax.bar(pos + delta, attacks, 0.35, label='Attack')

# Add labels and legend
ax.set_xticks(pos, categories)
ax.legend()

plt.show()

huangapple
  • 本文由 发表于 2023年3月12日 07:37:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710247.html
匿名

发表评论

匿名网友

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

确定