有没有一种方法可以将带有条形图的3条线图绘制为具有不同y轴的一个图形?

时间:2019-10-07 10:49:15

标签: python matplotlib bokeh

我想用条形图一起绘制3条线图,作为python熊猫中的一张图。如何将这些与不同的y轴一起绘制?例如,一条线图作为条形图的目标线,另一条线图作为另一条线图的目标。

因此,任务是将4个图绘制为单个图,我有2个不同的变量,一个是蛋白质%(它是条形图),另一个是卡路里(是线图),它们都共享相同的x轴,是几个月。现在,我想包括其他2条线图,每条线图都作为上述两个已定义变量的目标变量。两个折线图必须共享一个y轴,而另一个折线图必须与条形图共享另一个y轴。我设法将具有不同y轴的两个变量绘制为一张图,并且还设法使一个线图与一个变量共享一个y轴,但是现在我无法使另一条线图共享另一个y轴。轴与其他变量。

from bokeh.palettes import PuBu
from bokeh.io import show, output_notebook
from bokeh.models import ColumnDataSource, ranges, LabelSet, HoverTool
from bokeh.plotting import figure, show
from bokeh.models import LinearAxis, Range1d
# My word count data
months = nutrients_group.Month.tolist() 
p_percentage = nutrients_group.Protein_percetange.tolist()
calories = nutrients_group.Energy.tolist()
#protein_percent = [round(x) for x in p_percentage]
source = ColumnDataSource(dict(x=months, y=p_percentage))

# Output the visualization directly in the notebook
#output_notebook()

# Create a figure with a datetime type x-axis
fig = figure(title='Year overview with target',
             plot_height=400, plot_width=700,
             x_axis_label='Months', y_axis_label='Calories',
             x_minor_ticks=2,
             toolbar_location=None)







#labels = LabelSet(x=months, y=p_percentage)
fig.extra_y_ranges = {"Protein": Range1d(start=0, end=100)}
fig.add_layout(LinearAxis(y_range_name="Protein", axis_label='Protein %'), 'right')
fig.vbar(x='x',  top='y', 
         color='#27c738', width=0.75, 
         legend='Protein %', y_range_name= "Protein", source=source)

fig.line(x=months, y=130000, 
         color='purple', line_width=2,
         legend='Target 30%')
fig.line(x=months, y=240000, 
         color='red', line_width=2,
         legend='Calories Target 240000')

fig.line(x=months, y=calories, 
         color='#00b7f0', line_width=1,
         legend='Calories')
fig.y_range = Range1d(0, 400000)



fig.legend.location = 'top_right'

hover = HoverTool(
    tooltips=[
        ("month", "@x"),
        ("value", "@y")
    ]
)

# Let's check it out
fig.add_tools(hover)
show(fig)[enter image description here][1]

我希望目标线能够绘制共享两个不同y轴的变量。

1 个答案:

答案 0 :(得分:1)

如果您不介意为此切换到matplotlib:

import matplotlib.pyplot as plt

xs = [1, 2, 3, 4, 5]  # x values
bar_ys = [28, 20, 10, 40, 10]  # left y axis
line_ys = [10, 20, 35, 40, 60]  # right y axis


fig, bar_ax = plt.subplots()
bar_ax.bar(xs, bar_ys, color='blue')  # plot first y series (line)
bar_ax.set_xlabel('x values')  # label for x axis
bar_ax.set_ylabel('bar values')  # label for left y axis
bar_ax.tick_params('y', colors='blue')  # add color to left y axis     

line_ax = bar_ax.twinx()
line_ax.plot(xs, line_ys, color='red')  # plot second y series (bar)
line_ax.set_ylabel('line values')  # label for right y axis
line_ax.tick_params('y', colors='red')  # add color to right y axis

plt.show()

结果图:

enter image description here

要绘制多个线图,只需将新的调用添加到line_ax.plot,并在每个调用中传递新的Y值:

import matplotlib.pyplot as plt

xs = [1, 2, 3, 4, 5]  # x values
bar_ys = [28, 20, 10, 40, 10]  # left y axis
line_ys_1 = [10, 20, 35, 40, 60]  # right y axis
line_ys_2 = [40, 40, 40, 40, 40]  # right y axis
line_ys_3 = [10, 20, 10, 20, 60]  # right y axis


fig, bar_ax = plt.subplots()
bar_ax.bar(xs, bar_ys, color='blue')  # plot first y series (line)
bar_ax.set_xlabel('x values')  # label for x axis
bar_ax.set_ylabel('bar values')  # label for left y axis
bar_ax.tick_params('y', colors='blue')  # add color to left y axis     

line_ax = bar_ax.twinx()
line_ax.plot(xs, line_ys_1, color='red')  # plot second y series (bar)
line_ax.plot(xs, line_ys_2, color='green')  # plot second y series (bar)
line_ax.plot(xs, line_ys_3, color='yellow')  # plot second y series (bar)
line_ax.set_ylabel('line values')  # label for right y axis

plt.show()

结果图:

enter image description here

从本质上讲,您可以对ax.plotax.bar以及从plt.subplotsax.twinx获得的轴使用任何其他绘图类型的任意组合。在同一斧头实例上调用的图将共享相同的Y轴。