How to add multiple histograms in a figure using Matplotlib? - python

I'm using matplotlib to plot many histograms in one plot successfully:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1)
for i in range(0, 6):
data = np.random.normal(size=1000)
plt.hist(data, bins=30, alpha = 0.5)
plt.show()
However, I wish to export this plot in a pdf, using PdfPages. I want to add each histogram in a separate page, which I successfully do like this:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
np.random.seed(1)
fig = []
with PdfPages("exported_data.pdf") as pdf:
for i in range(0, 6):
data = np.random.normal(size=1000)
fig.append(plt.hist(data, bins=30, alpha = 0.5))
pdf.savefig(fig[i])
plt.close()
But I want another, 7th page with all the plots in one figure as shown above. How do I add many histograms in the same figure (so I can then add in the pdf page)? I see many tutorials on how to plot a grid of histograms within a figure but I haven't found one with all the histograms in one plot added to a figure.
Thanks,
Stam

You can run the loop to plot all histograms together (your first code snippet) after having run the loop to plot them separately (your second code snippet). Here is an example where the random arrays are saved in the datasets list during the first loop to be able to plot them together in the second loop. This solution works by using plt.gcf() which returns the current figure.
import numpy as np # v 1.19.2
import matplotlib.pyplot as plt # v 3.3.4
from matplotlib.backends.backend_pdf import PdfPages
np.random.seed(1)
datasets = []
with PdfPages("exported_data.pdf") as pdf:
# Plot each histogram, adding each figure to the pdf
for i in range(6):
datasets.append(np.random.normal(size=1000))
plt.hist(datasets[i], bins=30, alpha = 0.5)
pdf.savefig(plt.gcf())
plt.close()
# Plot histograms together using a loop then add the completed figure to the pdf
for data in datasets:
plt.hist(data, bins=30, alpha = 0.5)
pdf.savefig(plt.gcf())
plt.close()

Related

How to Create a Real-Time Color Map in Python?

I am trying to create a real-time colour map. I want to continuously change slightly the RGB values of some elements in the matrix to make up my colour map. I read data from an excel file and a part of my data looks like this
Then I want to show the colour change in my colour map in one figure like a video. I tried this code:
df=pd.read_excel(r"G:\3Y_individualProject\Crop_color_data.xlsx", usecols="C:E")
color_data_2d=np.array(df.iloc[0:101])
color_data_1d=np.reshape(color_data_2d,(300))
color_data=color_data_1d.reshape(5,20,3)
for x in range(5):
fig, ax = plt.subplots()
ax.imshow(color_data)
ax.set_aspect("equal")
plt.pause(0.05)
for i in range(3):
color_data[0,1,i]=color_data[0,1,i]+0.1
color_data[1,1,i]=color_data[1,1,i]+0.2
color_data[2,1,i]=color_data[1,1,i]+0.25
print(color_data)
But it plots many different figures instead of showing them in a figure as I expected. I've also just tried to learn and use matplotlib.animation. I have tried the code below:
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
from matplotlib import cm
from matplotlib.animation import FuncAnimation
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
import itertools
def changeColor(x):
fig, ax = plt.subplots()
ax.imshow(color_data)
ax.set_aspect("equal")
for i in range(3):
color_data[0,1,i]=color_data[0,1,i]+0.1
color_data[1,1,i]=color_data[1,1,i]+0.2
color_data[2,1,i]=color_data[1,1,i]+0.25
results=FuncAnimation(plt.gcf(), changeColor, interval=5)
plt.tight_layout()
plt.show()
But with that code, my figure doesn't even display anything. As said I am quite new to matplotlib.animation so can anyone show me how to use matplotlib.animation or any other way to plot a real-time color map in my case, please? Thank you so much!

Creating a histogram of Yearly Returns

I am trying to finish a task for a project and my task is to create a histogram of yearly returns of Dow Jones historical returns. I have uploaded a picture of the task and my progress below. The problem I have at this point is that I can't find a way to separate the years in the histogram as it shows in the task and I don't know how to modify the y-axix and the legend to show the information that is showing in the first picture.
Any help is appreciated
What I am trying to make and My progress so far
Here is my code:
# Importing packages
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
#setting the order
order=[-60,-50,-40,-30,-20,-10,
0,10,20,30,40,50,60,70]
#getting the data
dow_jones_returns = pd.read_csv('data/dow-jones-by-year-historical-annual-returns (2).csv')
dow_jones=pd.DataFrame(data=dow_jones_returns)
dow_jones['date']=pd.to_datetime(dow_jones['date'])
dow_jones['date']=pd.DatetimeIndex(dow_jones['date']).year
pd.to_numeric(dow_jones.value)
up_to_2019=dow_jones.iloc[0:99]
lastyear= dow_jones.iloc[-1]
#ploting the histogram
fig = plt.figure()
up_to_2019['value'].plot.hist(bins = order)
plt.show()
Hi to just give you some further directions,
Regarding the Textbox
the textbox looks like it contains the summary statistics of DataFrame.describe() + a few additional ones. You can create a textbox by utilzing a combination of .text() and .subplot()
I found this guide to be very useful for creating a textbox in a plot
Since we dont have the data,
here a pseudo code:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
textstr = str(up_to_2019['value'].describe())
ax.hist(up_to_2019['value'], bins = order)
# these are matplotlib.patch.Patch properties
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
# place a text box in upper left in axes coords
ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=10,
verticalalignment='top', bbox=props)
plt.show()
Regarding the y-axis:
1) Here is how you set the right label: plt.ylabel("Number of Observations\n(Probability in%)")
2) Than add the Ticks plt.yticks(np.arange(1,27))
Regarding the labels inside the bins
Thats rather tricky, one option, though definitely not advised would to also include the labels via the .text() method. I dont know if it helps but here is how you do this in R.
Also might helpful are these two links:
how-to-add-a-text-into-a-rectangle
Change color for the patches in a hist
Apparently calling plt.hist() has three return values one of which is callled patches. You can iterate over patches and i.e. change the color of these (see the link above) however I couldn't figure how to put a text to them.
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
x = [21,22,23,4,5,6,77,8,9,10,31,32,33,34,35,36,37,18,49,50,100]
num_bins = 5
n, bins, patches = plt.hist(x, num_bins, facecolor='blue', alpha=0.5)
for i,pat in enumerate(patches):
pat.set_test("Test") #this doesnt work sadly

How to insert a triangle/contour plot generated with GetDist into a Matplotlib subplot?

I'm doing some analysis on MCMC samples and I'm using the GetDist python package to create my contour plots. However the contour plots are only a part of the whole analysis, and I would like to show some other plots along with the contour plot in the same figure.
I'm using matplotlib to generate all my other plots, so my question is: is there any way to have a GetDist plot in a matplotlib subplot, so that I have a matplotlib figure with multiple plots and a GetDist plot in it?
I'm using GridSpec to split the figure in subplots (and also to split subplots in subsubplots).
I tried to set a particular subplot as the current axis before creating the triangle plot, and I also tried to look at the GetDist source code to find a way to pass the wanted subplot as an argument to GetDist, but with no luck.
Right now, my code looks something like this
import matplotlib.pyplot as plt
import getdist.plots
from matplotlib import gridspec
import numpy as np
import numpy.random
N = 4
# Generate mock random data
chain = np.array([numpy.random.normal(loc=(i+0.5), scale=(i+0.5), size=100000) for i in xrange(N)])
Names = [str(unichr(i+97)) for i in xrange(N)]
Labels = [str(unichr(i+97)) for i in xrange(N)]
Sample = getdist.MCSamples(samples=chain.T, names=Names, labels=Labels)
#Set up plot layout
fig = plt.figure(figsize=(10.5,12.5))
gs = gridspec.GridSpec(3, 2, width_ratios=[2,3], height_ratios=[10,0.5,4], wspace=0.2, hspace=.05)
Lplot = gridspec.GridSpecFromSubplotSpec(N, 1, subplot_spec=gs[0,0], hspace=0.)
Rplot = gridspec.GridSpecFromSubplotSpec(2,1,subplot_spec=gs[0,1], height_ratios=[4,1.265])
Dplot = plt.subplot(gs[2,0:2])
axL = [plt.subplot(Lplot[i]) for i in xrange(N)]
axR = plt.subplot(Rplot[1])
GD = plt.subplot(Rplot[0])
for i in axL+[axR]+[GD]+[Dplot]: i.set_xticks([]); i.set_yticks([])
plt.sca(GD)
# Generate triangle plot
g = getdist.plots.getSubplotPlotter()
g.triangle_plot(Sample, filled=True)
plt.savefig("outfile.pdf", bbox_inches='tight')
I would like to have my contour plot in the "GD" subplot.
Any help?

Save multiple figures in one pdf page, matplotlib

I'm trying to get my figures in just one pdf page, but I don't know how to do this. I found out that it's possible to save multiple figures in a pdf file with 'matplotlib.backends.backend_pdf', but it doesn't work for just one page.
Has anyone any ideas ? Convert the figures to just one figure ?
You can use matplotlib gridspec to have multiple plots in 1 window
http://matplotlib.org/users/gridspec.html
from matplotlib.gridspec import GridSpec
import random
import numpy
from matplotlib import pyplot as pl
fig = pl.figure(figsize=(12, 16))
G = GridSpec(2,2)
axes_1 = pl.subplot(G[0, :])
x = [random.gauss(3,1) for _ in range(400)]
bins = numpy.linspace(-10, 10, 100)
axes_1.hist(x, bins, alpha=0.5, label='x')
axes_2 = pl.subplot(G[1, :])
axes_2.plot(x)
pl.tight_layout()
pl.show()
You can change the rows and column values and can subdivide the sections.
The PDF backend makes one page per figure. Use subplots to get multiple plots into one figure and they'll all show up together on one page of the PDF.
Here is a solution provided by matplotlib:
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
with PdfPages('foo.pdf') as pdf:
#As many times as you like, create a figure fig and save it:
fig = plt.figure()
pdf.savefig(fig)
....
fig = plt.figure()
pdf.savefig(fig)
VoilĂ 
Find a full example here: multipage pdf matplotlib
And by the way, for one figure, you don't need matplotlib.backends.backend_pdf just add pdf extension like so:
plt.savefig("foo.pdf")

How to show multiple images in one figure?

I use Python lib matplotlib to plot functions, and I know how to plot several functions in different subplots in one figure, like this one,
And when handling images, I use imshow() to plot images, but how to plot multiple images together in different subplots with one figure?
The documentation provides an example (about three quarters of the way down the page):
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
fig = plt.figure()
a=fig.add_subplot(1,2,1)
img = mpimg.imread('../_static/stinkbug.png')
lum_img = img[:,:,0]
imgplot = plt.imshow(lum_img)
a.set_title('Before')
plt.colorbar(ticks=[0.1,0.3,0.5,0.7], orientation ='horizontal')
a=fig.add_subplot(1,2,2)
imgplot = plt.imshow(lum_img)
imgplot.set_clim(0.0,0.7)
a.set_title('After')
plt.colorbar(ticks=[0.1,0.3,0.5,0.7], orientation='horizontal')
# ---------------------------------------
# if needed inside the application logic, uncomment to show the images
# plt.show()
Basically, it's the same as you do normally with creating axes with fig.add_subplot...
Simple python code to plot subplots in a figure;
rows=2
cols=3
fig, axes = plt.subplots(rows,cols,figsize=(30,10))
plt.subplots_adjust(wspace=0.1,hspace=0.2)
features=['INDUS','RM', 'AGE', 'DIS','PTRATIO','MEDV']
plotnum=1
for idx in features:
plt.subplot(rows,cols,plotnum)
sns.distplot(data[idx])
plotnum=plotnum+1
plt.savefig('subplots.png')
go through below link for more detail
https://exploredatalab.com/how-to-plot-multiple-subplots-in-python-with-matplotlib/

Categories

Resources