Legend and title to line charts using matplotlib - pandas

I am plotting the below data frame using google charts.
Group G1 G2
Hour
6 19 1
8 1 2
I have plotted the above dataframe in line chart. But i am not able to add legend and title to the line chart. And also, I am trying to increase the size of the line charts as it appears to be very small. Not sure whether do we have these options in matplotlib. Any help would be appreciated.
import matplotlib.pyplot as plt
plt.plot(dft2)
plt.xlabel('Hour')
plt.ylabel('Count')
plt.show()

dfg2.plot(legend=True, figsize=(8,8))
plt.legend(ncol=3, bbox_to_anchor=[1.35, 1], handlelength=2, handletextpad=1, columnspacing=1, title='Legend')
plt.title('Title here!', color='black', fontsize=17)
plt.xlabel('Hour', fontsize=15)
plt.ylabel('Count', fontsize=15)
plt.show()

Related

How to determine the matplotlib legend?

I have 3 lists to plot as curves. But every time I run the same plt lines, even with the ax.legend(loc='lower right', handles=[line1, line2, line3]), these 3 lists jumps randomly in the legend like below. Is it possible to fix their sequences and the colors for the legend as well as the curves in the plot?
EDIT:
My code is as below:
def plot_with_fixed_list(n, **kwargs):
np.random.seed(0)
fig, ax1 = plt.subplots()
my_handles = []
for key, values in kwargs.items():
value_name = key
temp, = ax1.plot(np.arange(1, n+ 1, 1).tolist(), values, label=value_name)
my_handles.append(temp)
ax1.legend(loc='lower right', handles=my_handles)
ax1.grid(True, which='both')
plt.show()
plot_with_fixed_list(300, FA_Hybrid=fa, BP=bp, Ssym_Hybrid=ssym)
This nondeterminism bug resides with python==3.5, matplotlib==3.0.0. After I updated to python==3.6, matplotlib==3.3.2, problem solved.

Multiple different kinds of plots on a single figure and save it to a video

I am trying to plot multiple different plots on a single matplotlib figure with in a for loop. At the moment it is all good in matlab as shown in the picture below and then am able to save the figure as a video frame. Here is a link of a sample video generated in matlab for 10 frames
In python, tried it as below
import matplotlib.pyplot as plt
for frame in range(FrameStart,FrameEnd):#loop1
# data generation code within a for loop for n frames from source video
array1 = np.zeros((200, 3800))
array2 = np.zeros((19,2))
array3 = np.zeros((60,60))
for i in range(len(array2)):#loop2
#generate data for arrays 1 to 3 from the frame data
#end loop2
plt.subplot(6,1,1)
plt.imshow(DataArray,cmap='gray')
plt.subplot(6, 1, 2)
plt.bar(data2D[:,0], data2D[:,1])
plt.subplot(2, 2, 3)
plt.contourf(mapData)
# for fourth plot, use array2[3] and array2[5], plot it as shown and keep the\is #plot without erasing for next frame
not sure how to do the 4th axes with line plots. This needs to be there (done using hold on for this axis in matlab) for the entire sequence of frames processing in the for loop while the other 3 axes needs to be erased and updated with new data for each frame in the movie. The contour plot needs to be square all the time with color bar on the side. At the end of each frame processing, once all the axes are updated, it needs to be saved as a frame of a movie. Again this is easily done in matlab, but not sure in python.
Any suggestions
thanks
I guess you need something like this format.
I have used comments # in code to answer your queries. Please check the snippet
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(6,6))
ax1=fig.add_subplot(311) #3rows 1 column 1st plot
ax2=fig.add_subplot(312) #3rows 1 column 2nd plot
ax3=fig.add_subplot(325) #3rows 2 column 5th plot
ax4=fig.add_subplot(326) #3rows 2 column 6th plot
plt.show()
To turn off ticks you can use plt.axis('off'). I dont know how to interpolate your format so left it blank . You can adjust your figsize based on your requirements.
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(6,6)) #First is width Second is height
ax1=fig.add_subplot(311)
ax2=fig.add_subplot(312)
ax3=fig.add_subplot(325)
ax4=fig.add_subplot(326)
#Bar Plot
langs = ['C', 'C++', 'Java', 'Python', 'PHP']
students = [23,17,35,29,12]
ax2.bar(langs,students)
#Contour Plot
xlist = np.linspace(-3.0, 3.0, 100)
ylist = np.linspace(-3.0, 3.0, 100)
X, Y = np.meshgrid(xlist, ylist)
Z = np.sqrt(X**2 + Y**2)
cp = ax3.contourf(X, Y, Z)
fig.colorbar(cp,ax=ax3) #Add a colorbar to a plot
#Multiple line plot
x = np.linspace(-1, 1, 50)
y1 = 2*x + 1
y2 = 2**x + 1
ax4.plot(x, y2)
ax4.plot(x, y1, color='red',linewidth=1.0)
plt.tight_layout() #Make sures plots dont overlap
plt.show()

how to plot a dataframe with two different axes in pandas matplotlib

So my data frame is like this:
6month final-formula numPatients6month
160243.0 1 0.401193 417
172110.0 2 0.458548 323
157638.0 3 0.369403 268
180306.0 4 0.338761 238
175324.0 5 0.247011 237
170709.0 6 0.328555 218
195762.0 7 0.232895 190
172571.0 8 0.319588 194
172055.0 9 0.415517 145
174609.0 10 0.344697 132
174089.0 11 0.402965 106
196130.0 12 0.375000 80
and I am plotting 6month, final-formula column
dffinal.plot(kind='bar',x='6month', y='final-formula')
import matplotlib.pyplot as plt
plt.show()
till now its ok, it shows 6month in the x axis and final-formula in the y-axis.
what I want is that to show the numPatients6month in the same plot, but in another y axis.
according to the below diagram. I want to show numPatients6month in the position 1, or simply show that number on above each bar.
I tried to conduct that by twinx, but it seems it is for the case we have two plot and we want to plot it in the same figure.
fig = plt.figure()
ax = fig.add_subplot(111)
ax2 = ax.twinx()
ax.set_ylabel('numPatients6month')
I appreciate your help :)
This is the solution that resolved it.I share here may help someone :)
ax=dffinal.plot(kind='bar',x='6month', y='final-formula')
import matplotlib.pyplot as plt
ax2 = ax.twinx()
ax2.spines['right'].set_position(('axes', 1.0))
dffinal.plot(ax=ax2,x='6month', y='numPatients6month')
plt.show()
Store the AxesSubplot in a variable called ax
ax = dffinal.plot(kind='bar',x='6month', y='final-formula')
and then
ax.tick_params(labeltop=False, labelright=True)
This will, bring the labels to the right as well.
Is this enough, or would you like to also know how to add values to the top of the bars? Because your question indicated, one of the two would satisfy.

Tick labels overlap in pandas bar chart

TL;DR: In pandas how do I plot a bar chart so that its x axis tick labels look like those of a line chart?
I made a time series with evenly spaced intervals (one item each day) and can plot it like such just fine:
intensity[350:450].plot()
plt.show()
But switching to a bar chart created this mess:
intensity[350:450].plot(kind = 'bar')
plt.show()
I then created a bar chart using matplotlib directly but it lacks the nice date time series tick label formatter of pandas:
def bar_chart(series):
fig, ax = plt.subplots(1)
ax.bar(series.index, series)
fig.autofmt_xdate()
plt.show()
bar_chart(intensity[350:450])
Here's an excerpt from the intensity Series:
intensity[390:400]
2017-03-07 3
2017-03-08 0
2017-03-09 3
2017-03-10 0
2017-03-11 0
2017-03-12 0
2017-03-13 2
2017-03-14 0
2017-03-15 3
2017-03-16 0
Freq: D, dtype: int64
I could go all out on this and just create the tick labels by hand completely but I'd rather not have to baby matplotlib and let do pandas its job and do what it did in the very first figure but with a bar plot. So how do I do that?
Pandas bar plots are categorical plots. They create one tick (+label) for each category. If the categories are dates and those dates are continuous one may aim at leaving certain dates out, e.g. to plot only every fifth category,
ax = series.plot(kind="bar")
ax.set_xticklabels([t if not i%5 else "" for i,t in enumerate(ax.get_xticklabels())])
In contrast, matplotlib bar charts are numberical plots. Here a useful ticker can be applied, which ticks the dates weekly, monthly or whatever is needed.
In addition, matplotlib allows to have full control over the tick positions and their labels.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import dates
index = pd.date_range("2018-01-26", "2018-05-05")
series = pd.Series(np.random.rayleigh(size=100), index=index)
plt.bar(series.index, series.values)
plt.gca().xaxis.set_major_locator(dates.MonthLocator())
plt.gca().xaxis.set_major_formatter(dates.DateFormatter("%b\n%Y"))
plt.show()

plot ordering/layering julia pyplot

I have a subplot that plots a line (x,y) and a particular point (xx,yy). I want to highligh (xx,yy), so I've plotted it with scatter. However, even if I order it after the original plot, the new point still shows up behind the original line. How can I fix this? MWE below.
x = 1:10
y = 1:10
xx = 5
yy = 5
fig, ax = subplots()
ax[:plot](x,y)
ax[:scatter](xx,yy, color="red", label="h_star", s=100)
legend()
xlabel("x")
ylabel("y")
title("test")
grid("on")
You can change which plots are displayed on top of each other with the argument zorder. The matplotlib example shown here gives a brief explanation:
The default drawing order for axes is patches, lines, text. This
order is determined by the zorder attribute. The following defaults
are set
Artist Z-order
Patch / PatchCollection 1
Line2D / LineCollection 2
Text 3
You can change the order for individual artists by setting the zorder.
Any individual plot() call can set a value for the zorder of that
particular item.
A full example based on the code in the question, using python is shown below:
import matplotlib.pyplot as plt
x = range(1,10)
y = range(1,10)
xx = 5
yy = 5
fig, ax = plt.subplots()
ax.plot(x,y)
# could set zorder very high, say 10, to "make sure" it will be on the top
ax.scatter(xx,yy, color="red", label="h_star", s=100, zorder=3)
plt.legend()
plt.xlabel("x")
plt.ylabel("y")
plt.title("test")
plt.grid("on")
plt.show()
Which gives: