对齐线和分组的条形图
我正在尝试使用Python的Pandas库在条形图的顶部绘制线路图。条形图是来自数据框的集群图表,当本身绘制时看起来像:
线图是整个数据集上的平均值:
我可以成功地绘制两者如果使用所有线路图,则在同一轴对象上的数据集:
但是当我 切换群集条的数据帧实际使用条形图,并将其与线路图一起绘制,线图希望从第二个索引位置绘制,从而导致偏移。
这个问题对Matplotlib对bar和line的X轴的方式有一个有趣的评论图表,这可能在这里很重要,但是我无法弄清该如何处理该见解。
解决这个路线问题的好方法是什么?
复制的代码:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
table_data = {2019: {1: np.nan,
2: np.nan,
3: np.nan,
4: 1.4200000000000002,
5: 0.8193548387096775,
6: 1.420689655172414,
7: 0.4645161290322581,
8: 0.10322580645161289,
9: 0.29333333333333333,
10: 1.7741935483870968,
11: 0.32,
12: 6.703225806451614},
2020: {1: 5.52,
2: 12.613793103448277,
3: 0.9428571428571428,
4: 0.1793103448275862,
5: 0.39354838709677414,
6: 1.3866666666666667,
7: 1.9800000000000002,
8: 0.6689655172413793,
9: 0.19333333333333336,
10: 5.896774193548388,
11: 0.6896551724137931,
12: 4.103225806451613},
2021: {1: 2.7935483870967746,
2: 5.15,
3: 9.696774193548388,
4: 3.74,
5: 2.8967741935483873,
6: 0.9103448275862069,
7: 1.6516129032258065,
8: 0.3,
9: 0.38571428571428573,
10: 5.141935483870968,
11: 8.58,
12: 6.052173913043479},
2022: {1: 2.3923076923076922,
2: 31.678571428571427,
3: 8.761290322580646,
4: np.nan,
5: np.nan,
6: np.nan,
7: np.nan,
8: np.nan,
9: np.nan,
10: np.nan,
11: np.nan,
12: np.nan}}
means = {1: 3.6137931034482755,
2: 16.435294117647057,
3: 7.132530120481928,
4: 1.797752808988764,
5: 1.3698924731182796,
6: 1.240909090909091,
7: 1.358695652173913,
8: 0.3522727272727273,
9: 0.28863636363636364,
10: 4.2709677419354835,
11: 3.2247191011235956,
12: 5.578823529411765}
df_bars = pd.DataFrame(table_data)
df_means = pd.DataFrame.from_dict(means, orient = 'index', columns = ['Mean'])
# Clustered bar chart by itself
df_bars.plot(kind = 'bar',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)
# Line chart by itself
df_means.plot(
kind = 'line',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
y = 'Mean'
)
# Show all data as line charts. This works OK
ax_avg = df_bars.plot(kind = 'line',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)
df_means.plot(
ax = ax_avg,
kind = 'line',
y = 'Mean'
)
plt.show()
# Show bar data and line chart on the one plot. The line chart is offset!
ax_avg2 = df_bars.plot(kind = 'bar',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)
df_means.plot(
ax = ax_avg2,
kind = 'line',
y = 'Mean'
)
plt.show()
I am trying to plot a line chart on top of a bar chart using Python's pandas library. The bar chart is a clustered chart from a DataFrame and looks like so when plotted by itself:
The line chart is the averages across the whole dataset:
I can successfully plot both sets of data on the same axis object if using all line charts:
But when I switch the DataFrame for the clustered bar to actually using a bar chart and plot it along with the line chart, the line chart wants to plot from the second index position, leading to an offset.
The answer to this question has an interesting comment about the way matplotlib treats the x-axis for both bar and line charts, which may be relevant here, but I can't work out what to do with that insight.
What's a good way to fix this alignment issue?
Code to reproduce:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
table_data = {2019: {1: np.nan,
2: np.nan,
3: np.nan,
4: 1.4200000000000002,
5: 0.8193548387096775,
6: 1.420689655172414,
7: 0.4645161290322581,
8: 0.10322580645161289,
9: 0.29333333333333333,
10: 1.7741935483870968,
11: 0.32,
12: 6.703225806451614},
2020: {1: 5.52,
2: 12.613793103448277,
3: 0.9428571428571428,
4: 0.1793103448275862,
5: 0.39354838709677414,
6: 1.3866666666666667,
7: 1.9800000000000002,
8: 0.6689655172413793,
9: 0.19333333333333336,
10: 5.896774193548388,
11: 0.6896551724137931,
12: 4.103225806451613},
2021: {1: 2.7935483870967746,
2: 5.15,
3: 9.696774193548388,
4: 3.74,
5: 2.8967741935483873,
6: 0.9103448275862069,
7: 1.6516129032258065,
8: 0.3,
9: 0.38571428571428573,
10: 5.141935483870968,
11: 8.58,
12: 6.052173913043479},
2022: {1: 2.3923076923076922,
2: 31.678571428571427,
3: 8.761290322580646,
4: np.nan,
5: np.nan,
6: np.nan,
7: np.nan,
8: np.nan,
9: np.nan,
10: np.nan,
11: np.nan,
12: np.nan}}
means = {1: 3.6137931034482755,
2: 16.435294117647057,
3: 7.132530120481928,
4: 1.797752808988764,
5: 1.3698924731182796,
6: 1.240909090909091,
7: 1.358695652173913,
8: 0.3522727272727273,
9: 0.28863636363636364,
10: 4.2709677419354835,
11: 3.2247191011235956,
12: 5.578823529411765}
df_bars = pd.DataFrame(table_data)
df_means = pd.DataFrame.from_dict(means, orient = 'index', columns = ['Mean'])
# Clustered bar chart by itself
df_bars.plot(kind = 'bar',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)
# Line chart by itself
df_means.plot(
kind = 'line',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
y = 'Mean'
)
# Show all data as line charts. This works OK
ax_avg = df_bars.plot(kind = 'line',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)
df_means.plot(
ax = ax_avg,
kind = 'line',
y = 'Mean'
)
plt.show()
# Show bar data and line chart on the one plot. The line chart is offset!
ax_avg2 = df_bars.plot(kind = 'bar',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)
df_means.plot(
ax = ax_avg2,
kind = 'line',
y = 'Mean'
)
plt.show()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
reset_index
将行数据框架的索引更改为零。这将允许您的条形与基于零的索引对齐:
输出:
You can use
reset_index
to change the indexing of line dataframe back to start with zero.This will allow your bars to line up with zero-based indexing like this:
Output: