Reputation: 1966
My Problem:
I am havinging difficutly trying to get my line graph to centered with the y ticks. Currently there seems to be an offset to the left when I draw my graphs. Also I am having difficulty in trying to get both of the labels to appear in the same legend.
My Code:
f, ax1 = plt.subplots(1, figsize=(10, 5))
# Set the bar width
bar_width_tram = 1
bar_width_brake_percentage = 1
# Positions of the left bar-boundaries
bar_l = [i + 1 for i in range(len(data_frame['Tram Hrs']))]
# Positions of the x-axis ticks (center of the bars as bar labels)
tick_pos = [i + (bar_width_tram / 2) for i in bar_l]
# Define the colours for the corresponding
# bars in the graph
tram_data_hrs_colour = '#00AC00' # Green
bd_per_colour = '#DA0505' # Red
# Create a bar plot, in position bar_1
ax1.bar(bar_l,
# using the pre_score data
data_frame['Tram Hrs'],
# get rid of border lines
edgecolor="none",
# set the width
width=bar_width_tram,
# with the label pre score
label='Tramming Hours',
# with alpha 0.5
alpha=0.05,
# with color
color=tram_data_hrs_colour)
# Set the X-ticks with dates
plt.xticks(tick_pos, data_frame['Date'])
plt.yticks(np.arange(0, 15, 3))
# Set the labels and legend
ax1.set_ylabel("Tramming Time (Hours)")
ax1.set_xlabel("Previous Week")
# Second axis
ax2 = ax1.twinx()
ax2.set_ylabel("Braking to Tramming (%)")
plt.plot(bar_l,data_frame['Brake%'], '-', label='Relative Braking Percentage')
plt.yticks(np.arange(0, 250, 50))
# Set the title of the chart
plt.legend(loc='upper left')
My Questions:
Q1. How can I get the line graph to be centred/aligned with the x-tics in the bar graphs along the x-axis (i.e.currently they are left biased)?
Q2. How can I get both of the labels to appear in the legend?
Data:
Date Brake Hrs Tram Hrs Brake% Tram% Br/Tr%
0 Mon 0.87 4.26 16.90 83.10 20.33
1 Tue 1.00 3.05 24.66 75.34 32.73
2 Wed 1.77 3.87 31.44 68.56 45.85
3 Thu 1.86 5.16 26.44 73.56 35.94
4 Fri 1.41 2.01 41.15 58.85 69.93
5 Sat 0.01 5.03 0.14 99.86 0.14
6 Sun 0.40 1.16 25.82 74.18 34.82
Using columns Date
for x axis, and Tram Hrs
axis 1, Br/Tr%
for axis 2
Upvotes: 1
Views: 2420
Reputation: 7476
Concerning Q1, what you need to do is to set the bar alignment, adding align = 'center' to the ax.bar call (http://matthiaseisen.com/pp/patterns/p0177/)
For Q2, you can follow this SO answer: Single legend for multiple axes.
Finally, I have added at the bottom a call to plt.xlim to leave white space both sides of the chart.
Please find attached below proposed solution and output obtained:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
cols = ['Date', 'Brake Hrs', 'Tram Hrs', 'Brake%', 'Tram%', 'Br/Tr%']
data_frame = pd.DataFrame([['Mon', 0.87, 4.26, 16.90, 83.10, 20.33],
['Tue', 1.00, 3.05, 24.66, 75.34, 32.73],
['Wed', 1.77, 3.87, 31.44, 68.56, 45.85],
['Thu', 1.86, 5.16, 26.44, 73.56, 35.94],
['Fri', 1.41, 2.01, 41.15, 58.85, 69.93],
['Sat', 0.01, 5.03, 0.14, 99.86, 0.14],
['Sun', 0.40, 1.16, 25.82, 74.18, 34.82]],
columns = cols)
f, ax1 = plt.subplots(1, figsize=(10, 5))
# Set the bar width
bar_width_tram = 1
bar_width_brake_percentage = 1
# Positions of the left bar-boundaries
bar_l = [i + 1 for i in range(len(data_frame['Tram Hrs']))]
# Positions of the x-axis ticks (center of the bars as bar labels)
tick_pos = [i + (bar_width_tram / 2) for i in bar_l]
# Define the colours for the corresponding
# bars in the graph
tram_data_hrs_colour = '#00AC00' # Green
bd_per_colour = '#DA0505' # Red
# Create a bar plot, in position bar_1
ax1.bar(bar_l,
# using the pre_score data
data_frame['Tram Hrs'],
# get rid of border lines
edgecolor="none",
# set the width
width=bar_width_tram,
# with the label pre score
label='Tramming Hours',
# with alpha 0.5
alpha=0.05,
# with color
color=tram_data_hrs_colour,
align = 'center')
# Set the X-ticks with dates
plt.xticks(tick_pos, data_frame['Date'])
plt.yticks(np.arange(0, 15, 3))
# Set the labels and legend
ax1.set_ylabel("Tramming Time (Hours)")
ax1.set_xlabel("Previous Week")
# Second axis
ax2 = ax1.twinx()
ax2.set_ylabel("Braking to Tramming (%)")
plt.plot(bar_l,data_frame['Brake%'], '-', label='Relative Braking Percentage')
plt.yticks(np.arange(0, 250, 50))
# Set the title of the chart
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1+h2, l1+l2, loc=2)
plt.xlim(0, len(tick_pos) + 1)
This looks in line with your desired output. I am using matplotlib 1.5.1 and pandas 0.18.1
Upvotes: 2