如何在具有相同数量的 y 轴标记且两个 y 轴在 Python 中以 0 对齐的同一图上绘制 seaborn lineplot 和 barplot
How to plot seaborn lineplot and barplot on the same plot with same number of y-axes tickers and both y-axes aligned at 0 in Python
我在使用我将在下面显示的“结果”数据框中的数据(带有“a”数据、“b”数据、和“百分位数”)在 Python.
当我分别绘制它们时,我能够很好地绘制线图(使用“a”数据),但是,我尝试绘制的条形图的 x 轴值(使用 'b' 数据) 不显示。奇怪的是,我可以使用相同的数据绘制线图而没有任何问题,我正在尝试使用 ('b' data)
绘制条形图
当我尝试将它们绘制在同一个图上时,x 轴从一个甚至不存在于“结果”数据框中的日期开始。
我什至尝试将结果数据帧导出为 csv 并重新导入它以查看是否可行,但我 运行 遇到了同样的问题。
我想达到的目标:
- 在具有不同 y 轴的同一 seaborn 图上将“a”数据绘制为线图,将“b”数据绘制为条形图
- 我想要相同数量的 y 轴标记,并且要对齐两个 y 轴的 0
- 最后,我希望条形图的颜色取决于百分位数列是否表示“低”、“中”、“高”(每个颜色不同)
# Here is the 'a' and 'b' data that I start with
a = pd.read_csv(r'a.csv',sep=",", parse_dates=['date'], dayfirst=True, index_col=0)
b = pd.read_csv(r'b.csv',sep=",", parse_dates=['date'], dayfirst=True, index_col=0)
'a' DataFrame
'b' DataFrame
# After manipulating the data, here is the 'results' DataFrame I end up with
'results' DataFrame
# Plotting them separately
# Plotting lineplot using 'a' column from 'results' DataFrame
sns.lineplot(data=result.iloc[:, 0], color="g")
lineplot
# Plotting barplot using 'b' column from 'results' DataFrame
b_plot = sns.barplot(data=result, x=result.index, y=result.iloc[:, 2], color="b")
b_plot.xaxis.set_major_locator(md.YearLocator(base=4))
b_plot.xaxis.set_major_formatter(md.DateFormatter('%Y'))
b_plot.margins(x=0)
barplot
# Attempting to plot the lineplot and barplot on the same plot
matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None)
fig, ax1 = plt.subplots(figsize=(12,6))
a_plot = sns.lineplot(data=result.iloc[:, 0], color="g", ax=ax1)
ax2 = ax1.twinx()
b_plot = sns.barplot(data=result, x=result.index, y=result.iloc[:, 2], color="b", ax=ax2)
b_plot.xaxis.set_major_locator(md.YearLocator(base=4))
b_plot.xaxis.set_major_formatter(md.DateFormatter('%Y'))
b_plot.margins(x=0)
lineplot and barplot on same plot
编辑:我已经回答了下面的问题
这是我在评论中建议的示例。
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
data = pd.DataFrame({'Day': [1, 2, 3, 4], 'Value': [3, 7, 4, 2], 'Value 2': [1, 7, 4, 5]})
f, ax = plt.subplots()
sns.barplot(data=data, x='Day', y='Value')
编辑:在此处使用点图对齐条目。
sns.pointplot(data=data, x='Day', y='Value 2')
以下是我的问题的答案:
matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None)
fig, ax1 = plt.subplots(figsize=(12,6))
ax2 = ax1.twinx()
# plot the bar plot and make the colours dependent on the values in a seperate column
result_date = result.reset_index()
palette = {"low":"lightgreen",
"mid":"darkseagreen",
"high":"green"}
b_plot = sns.barplot(data = result_date, x=result_date.iloc[:, 0],
y=result_date.iloc[:, 3], ax=ax1, hue='percentile', palette=palette, dodge = False)
# plot the lineplot
a_plot = sns.pointplot(data=result, x=result.index, y=result.iloc[:, 0], color="black", ax=ax2, markers = 'o', scale=0.4)
# set the x tickers to be those of the bar plot
ax1.set_xticks(np.arange(len(result_date)))
ax1.set_xticklabels(result_date.date.apply(lambda x: str(x.year)))
ax1.xaxis.set_major_locator(ticker.AutoLocator())
# align axis at 0, and get same number of ticks on both y-axes
max1 = np.nanmax(np.abs(ax1.get_ybound()))
max2 = np.nanmax(np.abs(ax2.get_ybound()))
nticks = 7
ax1.set_yticks(np.linspace(-max1, max1, nticks))
ax2.set_yticks(np.linspace(-max2, max2, nticks))
我在使用我将在下面显示的“结果”数据框中的数据(带有“a”数据、“b”数据、和“百分位数”)在 Python.
当我分别绘制它们时,我能够很好地绘制线图(使用“a”数据),但是,我尝试绘制的条形图的 x 轴值(使用 'b' 数据) 不显示。奇怪的是,我可以使用相同的数据绘制线图而没有任何问题,我正在尝试使用 ('b' data)
绘制条形图当我尝试将它们绘制在同一个图上时,x 轴从一个甚至不存在于“结果”数据框中的日期开始。
我什至尝试将结果数据帧导出为 csv 并重新导入它以查看是否可行,但我 运行 遇到了同样的问题。
我想达到的目标:
- 在具有不同 y 轴的同一 seaborn 图上将“a”数据绘制为线图,将“b”数据绘制为条形图
- 我想要相同数量的 y 轴标记,并且要对齐两个 y 轴的 0
- 最后,我希望条形图的颜色取决于百分位数列是否表示“低”、“中”、“高”(每个颜色不同)
# Here is the 'a' and 'b' data that I start with
a = pd.read_csv(r'a.csv',sep=",", parse_dates=['date'], dayfirst=True, index_col=0)
b = pd.read_csv(r'b.csv',sep=",", parse_dates=['date'], dayfirst=True, index_col=0)
'a' DataFrame
'b' DataFrame
# After manipulating the data, here is the 'results' DataFrame I end up with
'results' DataFrame
# Plotting them separately
# Plotting lineplot using 'a' column from 'results' DataFrame
sns.lineplot(data=result.iloc[:, 0], color="g")
lineplot
# Plotting barplot using 'b' column from 'results' DataFrame
b_plot = sns.barplot(data=result, x=result.index, y=result.iloc[:, 2], color="b")
b_plot.xaxis.set_major_locator(md.YearLocator(base=4))
b_plot.xaxis.set_major_formatter(md.DateFormatter('%Y'))
b_plot.margins(x=0)
barplot
# Attempting to plot the lineplot and barplot on the same plot
matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None)
fig, ax1 = plt.subplots(figsize=(12,6))
a_plot = sns.lineplot(data=result.iloc[:, 0], color="g", ax=ax1)
ax2 = ax1.twinx()
b_plot = sns.barplot(data=result, x=result.index, y=result.iloc[:, 2], color="b", ax=ax2)
b_plot.xaxis.set_major_locator(md.YearLocator(base=4))
b_plot.xaxis.set_major_formatter(md.DateFormatter('%Y'))
b_plot.margins(x=0)
lineplot and barplot on same plot
编辑:我已经回答了下面的问题
这是我在评论中建议的示例。
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
data = pd.DataFrame({'Day': [1, 2, 3, 4], 'Value': [3, 7, 4, 2], 'Value 2': [1, 7, 4, 5]})
f, ax = plt.subplots()
sns.barplot(data=data, x='Day', y='Value')
编辑:在此处使用点图对齐条目。
sns.pointplot(data=data, x='Day', y='Value 2')
以下是我的问题的答案:
matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None)
fig, ax1 = plt.subplots(figsize=(12,6))
ax2 = ax1.twinx()
# plot the bar plot and make the colours dependent on the values in a seperate column
result_date = result.reset_index()
palette = {"low":"lightgreen",
"mid":"darkseagreen",
"high":"green"}
b_plot = sns.barplot(data = result_date, x=result_date.iloc[:, 0],
y=result_date.iloc[:, 3], ax=ax1, hue='percentile', palette=palette, dodge = False)
# plot the lineplot
a_plot = sns.pointplot(data=result, x=result.index, y=result.iloc[:, 0], color="black", ax=ax2, markers = 'o', scale=0.4)
# set the x tickers to be those of the bar plot
ax1.set_xticks(np.arange(len(result_date)))
ax1.set_xticklabels(result_date.date.apply(lambda x: str(x.year)))
ax1.xaxis.set_major_locator(ticker.AutoLocator())
# align axis at 0, and get same number of ticks on both y-axes
max1 = np.nanmax(np.abs(ax1.get_ybound()))
max2 = np.nanmax(np.abs(ax2.get_ybound()))
nticks = 7
ax1.set_yticks(np.linspace(-max1, max1, nticks))
ax2.set_yticks(np.linspace(-max2, max2, nticks))