how to plot histogram and time series in python - python

I have two different pandas dataframes from which I obtained the following graphs:
ar_month_mean.plot(figsize=(15,5))
hist_month.plot(kind='bar', figsize=(15,5))
I'd like to combine them to obtain something similar to this:

you can pass an ax to the plotting methods, to have multiple plots in the same ax. Otherwise, each new plot will be in a new axis:
import matplotlib.pyplot as plt
f = plt.figure(figsize=(15,5))
ax = plt.gca()
ar_month_mean.plot(ax=ax, figsize=(15,5))
hist_month.plot(ax=ax, kind='bar', figsize=(15,5))
If you post the actually data, I will upload the resulting figure.

Related

Plot data from two DataFrame with only one colorbar in a scatter plot

I have two DataFrame for two different datasets that contain columns RA,Dec, and Vel. I need to plot them to a same scatter plot and show one colorbar instead of two. There's similar question using pure matplotlib here, but I need to do it using scatter plot function from pandas. Here's my experiment so far:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data1 = pd.DataFrame({'RA':np.random.randint(-100,100,5),
'Dec':np.random.randint(-100,100,5),'Vel':np.random.randint(-20,10,5)})
data2 = pd.DataFrame({'RA':np.random.randint(-100,100,5),
'Dec':np.random.randint(-100,100,5),'Vel':np.random.randint(-10,20,5)})
fig, ax = plt.subplots(figsize=(12, 10))
data1.plot.scatter(x='RA',y='Dec',c='Vel',cmap='rainbow',
marker='^',ax=ax,label='Methanol',vmin=-20, vmax=20)
data2.plot.scatter(x='RA',y='Dec',c='Vel',cmap='rainbow',
marker='o',ax=ax,label='Water',vmin=-20, vmax=20)
ax.set_xlabel('$\Delta$RA (arcsec.)')
ax.set_ylabel('$\Delta$Dec. (arcsec.)')
ax.set_title('Maser Spot')
ax.invert_xaxis()
ax.legend(loc=2)
Using this code, I managed to plot two DataFrame into one scatter plot. But it shows two colorbars as you can see here:
Test Case.
Any help is appreciated.
You can just add colorbar = False in the first plot.
The final code will be :
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data1 = pd.DataFrame({'RA':np.random.randint(-100,100,5),
'Dec':np.random.randint(-100,100,5),'Vel':np.random.randint(-20,10,5)})
data2 = pd.DataFrame({'RA':np.random.randint(-100,100,5),
'Dec':np.random.randint(-100,100,5),'Vel':np.random.randint(-10,20,5)})
fig, ax = plt.subplots(figsize=(12, 10))
data1.plot.scatter(x='RA',y='Dec',c='Vel',cmap='rainbow',
marker='^',ax=ax,label='Methanol',vmin=-20, vmax=20,
colorbar=False)
data2.plot.scatter(x='RA',y='Dec',c='Vel',cmap='rainbow',
marker='o',ax=ax,label='Water',vmin=-20, vmax=20)
ax.set_xlabel('$\Delta$RA (arcsec.)')
ax.set_ylabel('$\Delta$Dec. (arcsec.)')
ax.set_title('Maser Spot')
ax.invert_xaxis()
ax.legend(loc=2)

How to make two separate plots in seaborn from the same dataframe in pandas?

I have a dataframe in pandas that I'm trying to create two separate plots from in the same function, one is an ordinary boxplot w/ jitter and the other is a violin plot.
I've tried saving them to two separate variables and then saving each of those to their own image files, but in each of those files, the plots seem to contain an overlay of both of them rather than each containing their own separate plot. Here's what the code looks like:
final_boxplot = sns.boxplot(data = df)
final_violin = sns.violinplot(data = df)
final_boxplot.figure.savefig('boxplot.png')
final_violin.figure.savefig('violin.png')
any ideas on what I might be doing wrong, or any alternatives?
You should create different instance of figures and
save:
fig,ax = plt.subplots()
sns.boxplot(data=df, ax=ax)
fig.savefig('boxplot.png')
fig, ax = plt.subplots()
sns.violinplot(data=df, ax=ax)
fig.savefig('violin.png')

How can I rotate annotated seaborn heatmap data and legend?

I created to a seaborn heatmap to summarize Teils_U coefficients. The data is horizontally displayed in the heatmap. Now, I would like to rotate the data and the legend. I know that you can roate the x axis and y axis labels in a plot, but how can I rotate the data and the legend ?
This is my code:
#creates padnas dataframe to hold the values
theilu = pd.DataFrame(index=['Y'],columns=matrix.columns)
#store column names in variable columns
columns = matrix.columns
#iterate through each variable
for j in range(0,len(columns)):
#call teil_u function on "ziped" independant and dependant variable -> respectivley x & y in the functions section
u = theil_u(matrix['Y'].tolist(),matrix[columns[j]].tolist())
#select respecive columns needed for output
theilu.loc[:,columns[j]] = u
#handle nans if any
theilu.fillna(value=np.nan,inplace=True)
#plot correlation between fraud reported (y) and all other variables (x)
plt.figure(figsize=(20,1))
sns.heatmap(theilu,annot=True,fmt='.2f')
plt.show()
Here an image of what I am looking for:
Please let me know if you need and sample data or the teil_u function to recreate the problem. Thank you
The parameters of the annotation can be changed via annot_kws. One of them is the rotation.
Some parameters of the colorbar can be changed via cbar_kwsdict, but the unfortunately the orientation of the labels isn't one of them. Therefore, you need a handle to the colorbar's ax. One way is to create an ax beforehand, and pass it to sns.heatmap(..., cbar_ax=ax). An easier way is to get the handle afterwards: cbar = heatmap.collections[0].colorbar.
With this ax handle, you can change more properties of the colorbar, such as the orientation of its labels. Also, their vertical alignment can be changed to get them centered.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
data = np.random.rand(1, 12)
fig, ax = plt.subplots(figsize=(10,2))
heatmap = sns.heatmap(data, cbar=True, ax=ax,
annot=True, fmt='.2f', annot_kws={'rotation': 90})
cbar = heatmap.collections[0].colorbar
# heatmap.set_yticklabels(heatmap.get_yticklabels(), rotation=90)
heatmap.set_xticklabels(heatmap.get_xticklabels(), rotation=90)
cbar.ax.set_yticklabels(cbar.ax.get_yticklabels(), rotation=90, va='center')
plt.tight_layout()
plt.show()
You can pass argument to ax.text() (which is used to write the annotation) using the annot_kws= argument.
Therefore:
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
fig, ax = plt.subplots(figsize=(8,8))
ax = sns.heatmap(flights, annot=True, fmt='d', annot_kws={'rotation':90})

Add multiple axes from different sources into same figure

I am using Python/matplotlib to create a figure whereby it has three subplots, each returned from a different 'source' or class method.
For example, I have a script called 'plot_spectra.py' that contains the Spectra() class with method Plot().
So, calling Spectra('filename.ext').Plot() will return a tuple, as per the code below:
# create the plot
fig, ax = plt.subplots()
ax.contour(xx, yy, plane, levels=cl, cmap=cmap)
ax.set_xlim(ppm_1h_0, ppm_1h_1)
ax.set_ylim(ppm_13c_0, ppm_13c_1)
# return the contour plot
return fig, ax
It is my understanding that the 'figure' is the 'window' in matplotlib, and the 'ax' is an individual plot. I would then want to say, plot three of these 'ax' objects in the same figure, but I am struggling to do so because I keep getting an empty window and I think I have misunderstood what each object actually is.
Calling:
hnca, hnca_ax = Spectra('data/HNCA.ucsf', type='sparky').Plot(plane_ppm=resi.N(), vline=resi.H())
plt.subplot(2,2,1)
plt.subplot(hnca_ax)
eucplot, barplot = PlotEucXYIntensity(scores, x='H', y='N')
plt.subplot(2,2,3)
plt.subplot(eucplot)
plt.subplot(2,2,4)
plt.subplot(barplot)
plt.show()
Ultimately, what I am trying to obtain is a single window that looks like this:
Where each plot has been returned from a different function or class method.
What 'object' do I need to return from my functions? And how do I incorporate these three objects into a single figure?
I would suggest this kind of approach, where you specify the ax on which you want to plot in the function:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
def Spectra(data, ax):
ax.plot(data)
def PlotIntensity(data, ax):
ax.hist(data)
def SeabornScatter(data, ax):
sns.scatterplot(data, data, ax = ax)
spectrum = np.random.random((1000,))
plt.figure()
ax1 = plt.subplot(1,3,1)
Spectra(spectrum, ax1)
ax2 = plt.subplot(1,3,2)
SeabornScatter(spectrum, ax2)
ax3 = plt.subplot(1,3,3)
PlotIntensity(spectrum, ax3)
plt.tight_layout()
plt.show()
You can specify the grid for the subplots in very different ways, and you probably also want to have a look on the gridspec module.
One way to do this is:
f = plt.figure()
gs = f.add_gridspec(2,2)
ax = f.add_subplot(gs[0,:])
Think of the '2,2' as adding 2 row x 2 columns.
On the third line 'gs[0,:]' is telling to add a chart on row 0, all columns. This will create the chart on the top of your top. Note that indices begin with 0 and not with 1.
To add the 'eucplot' you will have to call a different ax on row 1 and column 0:
ax2 = f.add_subplot(gs[1,0])
Lastly, the 'barplot' will go in yet a different ax on row 1, column 1:
ax3 = f.add_subplot(gs[1,1])
See this site here for further reference: Customizing Figure Layouts Using GridSpec and Other Functions

How to adjust and shape the subplots?

I am trying to plot 2 plots in one figure. So just 2 subplots and adjust the figure sizes and find a decent one. At the moment I am using this code:
import matplotlib.pyplot as plt
import pandas as pd
#import numpy as np
##### import data #####
df=pd.read_csv('C:\\Users\Kevin\Documents\Afstudeer\Measurements/1st_plot.txt',sep=',',decimal='.',header=None)
df.columns=['Vx','Vy','undefined','Laser_signal']
fig, ax = plt.subplots(figsize=(8, 5))
ax1=fig.add_subplot(121)
ax1.plot(df['Vx'],df['Vy'],label='plot')
plt.xlabel(r'$V_x$')
plt.ylabel(r'$V_y$')
ax2=fig.add_subplot(122)
ax1.scatter(df['Vx'],df['Vy'],label='data_points')
plt.xlabel(r'$V_x$')
plt.ylabel(r'$V_y$')
plt.subplots_adjust(left=.2, bottom=.45, right=.8, top=.95,
wspace=.3, hspace=.4)
so its this last code that is confusing me. When i do the plot, i get something like this:
Here is my sample data:
-1.725953467,0.109343505,-10.433363664,0.159675246
-1.725953467,0.110607445,-10.433363664,0.159675246
-1.729140157,0.110607445,-10.433363664,0.159675246
-1.722766777,0.10839555,-10.433363664,0.159675246
-1.727865481,0.11534722,-10.433363664,0.159359499
-1.726272136,0.112503355,-10.433363664,0.159675246
-1.731689509,0.120086995,-10.433363664,0.159359499
-1.727228143,0.117559115,-10.433363664,0.159359499
-1.729140157,0.11977101,-10.433363664,0.159675246
-1.730096164,0.121350935,-10.433363664,0.159675246
-1.729458826,0.122614875,-10.433363664,0.159043752
-1.735832206,0.12482677,-10.433363664,0.159359499
-1.728821488,0.121350935,-10.433363664,0.159675246
-1.733920192,0.124510785,-10.433363664,0.159359499
-1.731052171,0.12166692,-10.433363664,0.159675246
-1.739018896,0.12735465,-10.433363664,0.159043752
-1.738062889,0.12861859,-10.433363664,0.159043752
-1.738700227,0.133358365,-10.433363664,0.159043752
-1.73455753,0.12988253,-10.433363664,0.159043752
-1.743161593,0.144101855,-10.433363664,0.159043752
As you will see from the code, I am only taking the 1st 2 columns. I am expecting 2 subplots in a one figure. So why do i get these up and bottom lines between the plots??
The two lines
fig, ax = plt.subplots(figsize=(8, 5))
ax1=fig.add_subplot(121)
are somehow mutually exclusive. Either you create the subplots via
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 5))
or you create them via
fig = plt.figure()
ax1=fig.add_subplot(121)
ax2=fig.add_subplot(122)
After that better use the axes handles ax1 and ax2 to set any properties, e.g.
ax1.set_xlabel(r'$V_x$')
instead of plt.xlabel.

Categories