Matplotlib format the scale label - python

I have searched around SO and haven't been able to find how to format this text (I've also checked around google and the matplotlib docs)
I'm currently creating a figure and then adding 4 subplots in a 2x2 matrix format so I'm trying to scale down all the text:
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax1.tick_params(labelsize='xx-small')
ax1.set_title(v, fontdict={'fontsize':'small'})
ax1.hist(results[v], histtype='bar', label='data', bins=bins, alpha=0.5)
ax1.hist(results[v+'_sim'], histtype='bar', label='truth', bins=bins, alpha=0.8)
ax1.legend(loc='best', fontsize='x-small')

You can set the parameters before plot:
plt.rcParams['xtick.labelsize'] = "xx-small"
plt.rcParams['ytick.labelsize'] = "xx-small"

Related

Modifying subplots sizes

I have been trying to find some answers, but most of them don't include a table, or they solve the problem generally and I get in trouble trying to find a workaround with the table I created as I managed to put the table through an empty axis. But now decreasing the right-axis size (as the table gets accommodated to the axis size) and increasing the left two-axis size is becoming a daunting task.
I have this code:
fig = plt.figure(figsize=(18,5))
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(223)
ax3 = fig.add_subplot(122)
ax3.axis('off')
data = pd.DataFrame({'metrics': ['MSLE train', 'msle_test', 'asdsad'],
'values': [0.43, 0.52, 0.54]})
ax3.table(cellText=data.values, colLabels=data.columns, loc='center')
fig.suptitle(f'Train MSLE: {msle_train}, Test MSLE: {msle_test}')
ax1 = y_data.plot(label='Original data', ax=ax1, c='blue')
ax1 = y_pred_train.plot(ax=ax1, c='orange')
ax1 = y_pred_test.plot(ax=ax1, c='orange', linestyle='--')
ax1.legend()
ax2 = error_train.plot(label='Train error', ax=ax2)
ax2 = error_test.plot(label='Test error', ax=ax2, linestyle='--')
ax2.legend()
plt.show()
That returns this plot:
I'm looking to increase the horizontal size of the two left plots, something near the red mark:
Any suggestions?
You can use gridspec.
It even works with a vertical centered right hand side and a table:
import matplotlib.pyplot as plt
from matplotlib import gridspec
import pandas as pd
data = pd.DataFrame({'metrics': ['MSLE train', 'msle_test', 'asdsad'],
'values': [0.43, 0.52, 0.54]})
fig = plt.figure(figsize=(18,5))
gs = gridspec.GridSpec(4, 2, width_ratios=[3,1])
ax1 = fig.add_subplot(gs[0:2,:-1])
ax1.set_title('ax1')
ax2 = fig.add_subplot(gs[2:4,:-1])
ax2.set_title('ax2')
ax3 = fig.add_subplot(gs[1:3,1])
ax3.set_axis_off()
ax3.table(cellText=data.values, colLabels=data.columns, loc='center')
fig.tight_layout()
plt.show()
Notes:
Horizontal alignment is set with the ratio of width_ratios=[3,1]
fig.tight_layout() is helpfull to automatically align the spacing between the plots.
Vertical centering is achieved with a little workaround by having initially a larger vertical grid than required (no. of vertical plots) and distributing the plots and table accordingly (see e.g. gs[2:4).
The titles were just added for visual orientation.
ax3.set_axis_off() is required to suppress the plot frame at the table position - without it you'll get:

Removing Lines from Contourf in Matplotlib

I am using the following code to contour plot some data using contourf in matplotlib. I have set the transparency of the colourbar to 0.6, but there are annoying lines between each colour interval that I cant get rid of. There doesnt seem to be a way to set linestyle in contourf, any ideas?
#instantiating and titiling the figure
fig, ax1 = plt.subplots(figsize=(7,5))
fig.suptitle('Testing Simple Neural Networks', y=0.96, fontsize=16, fontweight='bold');
#defining colour tables
cm = plt.cm.coolwarm
#plotting the contour plot
levels = np.linspace(0, 1, 25)
cont1 = ax1.contourf(p1_mesh, p2_mesh, y_mesh, levels=levels, cmap=cm, alpha=0.6, linewidths=10)
#plotting the entire dataset - training and test data.
scat1 = ax1.scatter(X['p1'],
X['p2'],
c=y,
cmap=cm,
edgecolors='k');
#setting axis and legend
ax1.set(ylabel='p2',
xlabel='p1',
xlim=(0,255),
ylim=(0,255));
ax1.legend(*scat1.legend_elements(), title='Target');
ax1.set_axisbelow(True)
ax1.grid(color='xkcd:light grey')
cbar = fig.colorbar(cont1)
You can add the option antialiased=True to ax1.contourf, it should fix it.

Plot audio waveform and spectrogram overlap

I am working with audio using librosa, and I need to plot the spectrogram and waveform in the same display.
My code:
plt.figure(figsize=(14, 9))
plt.figure(1)
plt.subplot(211)
plt.title('Spectrogram')
librosa.display.specshow(stft_db, x_axis='time', y_axis='log')
plt.subplot(212)
plt.title('Audioform')
librosa.display.waveplot(y, sr=sr)
Using this code I get this plot
But I need something like this
According to librosa, you're able to provide the display methods with an axes to draw the item on, specshow, waveplot. I'd recommend defining your matplotlib figure and subplots outright, and then giving librosa the axes to plot them on.
fig = plt.figure(figsize=(14, 9)) #This setups the figure
ax1 = fig.subplots() #Creates the Axes object to display one of the plots
ax2 = ax1.twinx() #Creates a second Axes object that shares the x-axis
librosa.display.specshow(stft_db, x_axis='time', y_axis='log', ax=ax1)
librosa.display.waveplot(y, sr=sr, ax=ax2)
plt.show()
There might be some more formatting to be done to get the desired look, I'd recommend taking a look at this example from matplotlib, for a similar shared axes plot.
Instead of using subplots use the same axes of a single plot to display both the graphs.
fig = plt.figure(figsize=(14, 9))
ax = librosa.display.specshow(stft_db, x_axis='time', y_axis='log')
librosa.display.waveplot(y, sr=sr, ax=ax)
plt.show()

pyplot hist, plotting binned data

Here is the code non-binned plot of the data.
link_weights = [float(s)/float(k) for s,k in zip(strengths, degrees)]
fig2 = plt.figure()
ax = fig2.add_subplot(121)
ax.set_xlabel('degree [k]')
ax.set_ylabel('Average link weight <w>')
ax.scatter(degrees, link_weights, alpha=0.5)
ax = fig2.add_subplot(122)
ax.set_xlabel('degree [k]')
ax.set_ylabel('Average link weight <w>')
ax.set_xscale('log')
ax.scatter(degrees, link_weights, alpha=0.5)
fig2.savefig("figure-1b-1.pdf", ftype='pdf')
I want to plot histogram of binned data (bin-averaged versions of the plots). I managed to create binned data but stuck with plotting.
n_bins = 20
fig3 = plt.figure()
ax = fig3.add_subplot(121)
bin_means, bin_edges, _= stats.binned_statistic(link_weights, degrees,
statistic='mean', bins=n_bins)
I need to know how to plot bin_means as a histogram (lin x-axis and log x-axis). My initial attempt is below but it failed.
ax.hist(bin_means, n_bins, normed=True, histtype='bar')
Any help would be greatly appreciated. Thank you.

Importing histogram from matplotlib to plotly

I have generated these histograms with the python code below, and it looks fine in maptlotlib:
d_norm_1 = np.random.normal(loc=0.0, scale=3.0, size=5000)
## Build a Gaussian Mixture Model:
array1 = np.random.normal(loc=4.0, scale=2.0, size=2000)
array2 = np.random.normal(loc=-5.0, scale=4.0, size=2000)
d_norm_2 = np.concatenate((array1, array2))
fig3 = plt.figure(3, figsize=(8, 6))
ax3 = fig3.add_subplot(1, 1, 1)
plt.hist(d_norm_1, bins=40, normed=True, color='b', alpha=0.4, rwidth=1.0)
plt.hist(d_norm_2, bins=40, normed=True, color='g', alpha=0.4, rwidth=0.8)
plt.xlabel('$x$', size=20)
plt.ylabel('Probability Density', size=20)
plt.title('Histogram', size=20)
plt.setp(ax3.get_xticklabels(), rotation='horizontal', fontsize=16)
plt.setp(ax3.get_yticklabels(), rotation='horizontal', fontsize=16)
plt.show()
But when I import this into plotly, the histogram bars are replaced by lines. I think plotly is not compatible with this version of matplotlib.
Here is the plotly version of the same histogram shown above:
https://plot.ly/~vmirjalily/11/histogram/
I am using matplotlib 1.4.2
Your code histogram to plotly is working.
You are just missing one last step. What your plotly shows is a grouped bar chart. Eseentially what plotly has done is display 2 bars in a single column.
What you need to do, is go to
traces > mode and change to 'overlay' bar chart
here's my implementation
https://plot.ly/1/~quekxc
biobirdman's solution is perfectly fine if you want to use the web tools. Here's another way to do it strictly from Python:
import matplotlib.pyplot as plt
import numpy as np
import plotly.plotly as py
d_norm_1 = np.random.normal(loc=0.0, scale=3.0, size=5000)
## Build a Gaussian Mixture Model:
array1 = np.random.normal(loc=4.0, scale=2.0, size=2000)
array2 = np.random.normal(loc=-5.0, scale=4.0, size=2000)
d_norm_2 = np.concatenate((array1, array2))
fig3 = plt.figure(3, figsize=(8, 6))
ax3 = fig3.add_subplot(1, 1, 1)
plt.hist(d_norm_1, bins=40, normed=True, color='b', alpha=0.4, rwidth=1.0)
plt.hist(d_norm_2, bins=40, normed=True, color='g', alpha=0.4, rwidth=0.8)
plt.xlabel('$x$', size=20)
plt.ylabel('Probability Density', size=20)
plt.title('Histogram', size=20)
plt.setp(ax3.get_xticklabels(), rotation='horizontal', fontsize=16)
plt.setp(ax3.get_yticklabels(), rotation='horizontal', fontsize=16)
# note the `update` argument, it's formatted as a plotly Figure object
# this says: "convert the figure as best you can, then apply the update on the result"
py.iplot_mpl(fig3, update={'layout': {'barmode': 'overlay'}})
For more online info, checkout https://plot.ly/matplotlib/ or https://plot.ly/python/
For python help, checkout help(py.iplot_mpl) or help(Figure)
It can sometimes be useful to see exactly what got converted as well, you might try this:
import plotly.tools as tls
pfig = tls.mpl_to_plotly(fig3) # turns the mpl object into a plotly Figure object
print pfig.to_string() # prints out a `pretty` looking text representation

Categories

Resources