I'm trying to merge a line plot and a bar plot into one plot. The data source is a pandas dataframe.
Here is a demo:
import pandas as pd
test = {"index": range(10),
"line": [i**2 for i in range(10)],
"bar": [i*10 for i in range(10)]}
test=pd.DataFrame(test)
ax=test.plot(x="index",y="line")
test.plot(x="index",y="bar",color="r",kind="bar",ax=ax)
Everything is good until now, you can see the line is above the bars. If I ask the barplot using the secondary yaxis on the right by changing the last line as:
test.plot(x="index",y="bar",color="r",kind="bar",ax=ax, secondary_y=True)
Then the bars will on top of the line which is not what I desired.
Here are the two plots:
I tried to plot the bars first and then plot the line and I also tried to use zorder
to force the line above the bar but neither of them work.
Any suggestions or help would be appreciated.
rot : This keyword argument allows to rotate the markings on the x axis for a horizontal plotting and y axis for a vertical plotting. fontsize : Allows to set the font size for the labels and axis points. colormap : This keyword argument allows to choose different colour sets for the plots.
Use DataFrame.reset_index() function reset_index() to reset the index of the updated DataFrame. By default, it adds the current row index as a new column called 'index' in DataFrame, and it will create a new row index as a range of numbers starting at 0.
In order to sort the data frame in pandas, function sort_values() is used. Pandas sort_values() can sort the data frame in Ascending or Descending order.
The second axes will always be on top of the first. So you need to plot the line plot last to have it appear on top of the bars. You may consider the following solution, which sets the line to the secondary scale:
import pandas as pd
test = {"index": range(10),
"line": [i**2 for i in range(10)],
"bar": [100*i*10 for i in range(10)]}
test=pd.DataFrame(test)
ax = test.plot(x="index",y="bar",color="r",kind="bar")
ax2 = test.plot(x="index",y="line", color="b", ax=ax, secondary_y=True)
ax.set_ylabel("bar", color="r")
ax2.set_ylabel("line", color="b")
If you then want to have the scale for line on the left side of the plot, you can exchange the scales afterwards:
import pandas as pd
test = {"index": range(10),
"line": [i**2 for i in range(10)],
"bar": [100*i*10 for i in range(10)]}
test=pd.DataFrame(test)
ax = test.plot(x="index",y="bar",color="r",kind="bar")
ax2 = test.plot(x="index",y="line", color="b", ax=ax, secondary_y=True)
ax.yaxis.tick_right()
ax2.yaxis.tick_left()
ax.set_ylabel("bar", color="r")
ax2.set_ylabel("line", color="b")
ax.yaxis.set_label_position("right")
ax2.yaxis.set_label_position("left")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With