I'm new to programming so this is a basic question. I am creating a number of subplots in a big loop and wish to annotate each one with both a description and a value for that plot, e.g. Alpha = 5. But I find that using ax.text I can create one part or the other, but not both. The following code snippet produces roughly the desired outcome, but only when I run ax.text twice and position them manually, which of course is impractical.
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
i=0
for alpha,beta in [(5,10),(100,20)]:
for omega in ['A','B']:
i+=1
ax=plt.subplot(2,2,i)
ax.text(0.1,0.9,'Alpha = ')
ax.text(0.25,0.9,alpha)
plt.show()
I've tried various combinations of commas, plus signs and indices in ax.text but can't seem to get it to work.
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
i=0
for alpha,beta in [(5,10),(100,20)]:
for omega in ['A','B']:
i+=1
ax=plt.subplot(2,2,i)
ax.text(0.1,0.9,'Alpha = {}'.format(alpha))
plt.show()
Using formatting to do this
Related
I am trying to plot a scatter diagram. It will take multiple arrays as input but plot into a single graph.
Here is my code:
import numpy as np
import os
import matplotlib.pyplot as plt
ax = plt.gca()
n_p=np.array([17.2,25.7,6.1,0.9,0.5,0.2])
n_d=np.array([1,2,3])
a_p=np.array([4.3,1.4,8.1,1.8,7.9,7.0])
a_d=np.array([12,13,14])
ax.scatter = ([n_d[0]/n_d[1]],[n_p[0]/n_p[1]])
ax.scatter = ([a_d[0]/a_d[1]],[a_p[0]/a_p[1]])
I will read the arrays from csv file, here I just put a simple example (for that I imported os). I want to plot the ratio of array element 2/ element 1 of n_p (as x-axis) and same with n_d (as y-axis). This will give a point in the graph. Similar operation will be followed by a_p and a_d array, and the point will be appended to the graph. There will be more data to append, but to understand the process, two is enough.
I tried to follow example from here.
If I use the color, I get syntax error.
If I do not use color, I get a blank plot.
Sorry, my coding experience is beginner so code is rather nasty.
Thanks in advance.
remove the = from the function call!
import numpy as np
import os
import matplotlib.pyplot as plt
ax = plt.gca()
n_p=np.array([17.2,25.7,6.1,0.9,0.5,0.2])
n_d=np.array([1,2,3])
a_p=np.array([4.3,1.4,8.1,1.8,7.9,7.0])
a_d=np.array([12,13,14])
ax.scatter([n_d[0]/n_d[1]],[n_p[0]/n_p[1]])
ax.scatter([a_d[0]/a_d[1]],[a_p[0]/a_p[1]])
I want make a graph of a part of the values of a dictionary.
I already stored the necessary values in a variable, but I just don't understand how to put them in a simple graph with just the numbers 1 to 500 on the x-axis and my values on the y-axis.
%matplotlib inline
import matplotlib.pyplot as plt
# Plot frequencies of the most 500 words
frequencies = freqs_sorted[len(freqs_sorted)-500:len(freqs_sorted)]
Everything I tried so far resulted in an empty graph. Thanks in advance!
From the matplotlib tutorial:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.plot(range(1, 501), frequencies)
plt.show()
P.S. In matplotlib you often have several ways to draw whatever you want. It is just one of them. Here is shorter version from #gboffi:
plt.plot(frequencies)
plt.show()
I am looping through a bunch of CSV files containing various measurements.
Each file might be from one of 4 different data sources.
In each file, I merge the data into monthly datasets, that I then plot in a 3x4 grid. After this plot has been saved, the loop moves on and does the same to the next file.
This part I got figured out, however I would like to add a visual clue to the plots, as to what data it is. As far as I understand it (and tried it)
plt.subplot(4,3,1)
plt.hist(Jan_Data,facecolor='Red')
plt.ylabel('value count')
plt.title('January')
does work, however this way, I would have to add the facecolor='Red' by hand to every 12 subplots. Looping through the plots wont work for this situation, since I want the ylabel only for the leftmost plots, and xlabels for the bottom row.
Setting facecolor at the beginning in
fig = plt.figure(figsize=(20,15),facecolor='Red')
does not work, since it only changes the background color of the 20 by 15 figure now, which subsequently gets ignored when I save it to a PNG, since it only gets set for screen output.
So is there just a simple setthecolorofallbars='Red' command for plt.hist(… or plt.savefig(… I am missing, or should I just copy n' paste it to all twelve months?
You can use mpl.rc("axes", color_cycle="red") to set the default color cycle for all your axes.
In this little toy example, I use the with mpl.rc_context block to limit the effects of mpl.rc to just the block. This way you don't spoil the default parameters for your whole session.
import matplotlib as mpl
import matplotlib.pylab as plt
import numpy as np
np.random.seed(42)
# create some toy data
n, m = 2, 2
data = []
for i in range(n*m):
data.append(np.random.rand(30))
# and do the plotting
with mpl.rc_context():
mpl.rc("axes", color_cycle="red")
fig, axes = plt.subplots(n, m, figsize=(8,8))
for ax, d in zip(axes.flat, data):
ax.hist(d)
The problem with the x- and y-labels (when you use loops) can be solved by using plt.subplots as you can access every axis seperately.
import matplotlib.pyplot as plt
import numpy.random
# creating figure with 4 plots
fig,ax = plt.subplots(2,2)
# some data
data = numpy.random.randn(4,1000)
# some titles
title = ['Jan','Feb','Mar','April']
xlabel = ['xlabel1','xlabel2']
ylabel = ['ylabel1','ylabel2']
for i in range(ax.size):
a = ax[i/2,i%2]
a.hist(data[i],facecolor='r',bins=50)
a.set_title(title[i])
# write the ylabels on all axis on the left hand side
for j in range(ax.shape[0]):
ax[j,0].set_ylabel(ylabel[j])
# write the xlabels an all axis on the bottom
for j in range(ax.shape[1]):
ax[-1,j].set_xlabel(xlabels[j])
fig.tight_layout()
All features (like titles) which are not constant can be put into arrays and placed at the appropriate axis.
I'm charting the progress of a differential equation solver (boundary value problem). Each iteration yields a complete set of function evaluations f(x), which can then be plotted against x. Each graph is (supposedly) closer to the correct solution than the last until convergence is reached. A sequential colormap is used to make earlier graphs faded and later ones saturated.
This works fine when the number of iterations is predetermined:
import matplotlib.pyplot as plt
ax = plt.subplot(111)
cm = plt.get_cmap('OrRd')
ax.set_color_cycle([cm(1.*i/(iter+1)) for i in range(1,iter+2)])
ax.plot(x,y)
for k in range(iter):
# iterative solve
ax.plot(x,y)
However, if I use a convergence criterion instead of a predetermined number of iterations, I won't be able to set_color_cycle beforehand. And putting that line after the loop doesn't work.
I know that I can store my intermediate results and plot only after convergence is reached, but this strikes me as heavy-handed because I really have no use for all the intermediate results other than to see them on the plot.
So here are my questions:
1. How do I change the colormap of the existing graphs after plotting? (This is easy in MATLAB.)
2. How do I do the same thing with another collection of graphs on the same plot (e.g. from a different initial guess, converging to a different solution) without disturbing the first collection, so that two colormaps distinguish the collections from one another. (This should be obvious with the answer to Question 1, but just in case.)
Many thanks.
You can also use plt.set_cmap, see here or (more elaborately, scroll down) here:
import numpy as np
import matplotlib.pyplot as plt
plt.imshow(np.random.random((10,10)), cmap='magma')
plt.colorbar()
plt.set_cmap('viridis')
Use the update_colors() to update the colors of all lines:
import pylab as pl
import numpy as np
cm = pl.get_cmap('OrRd')
x = np.linspace(0, 1, 100)
def update_colors(ax):
lines = ax.lines
colors = cm(np.linspace(0, 1, len(lines)))
for line, c in zip(lines, colors):
line.set_color(c)
fig, ax = pl.subplots()
for i in range(10):
ax.plot(x, x**(1+i*0.1))
update_colors(ax)
One trick you could consider is rather than trying to change the colour values after plotting you can use a black overlay with less than 100% transparency to "fade" the past plots, e.g. an alpha of 10% would reduce the brightness of each past plot sequentially.
I am trying to make a matplotlib figure that will have multiple horizontal boxplots stacked on one another. The documentation shows both how to make a single horizontal boxplot and how to make multiple vertically oriented plots in this section.
I tried using subplots as in the following code:
import numpy as np
import pylab as plt
totfigs = 5
plt.figure()
plt.hold = True
for i in np.arange(totfigs):
x = np.random.random(50)
plt.subplot('{0}{1}{2}'.format(totfigs,1,i+1))
plt.boxplot(x,vert=0)
plt.show()
My output results in just a single horizontal boxplot though.
Any suggestions anyone?
Edit: Thanks to #joaquin, I fixed the plt.subplot call line. Now the subplot version works, but still would like the boxplots all in one figure...
If I'm understanding you correctly, you just need to pass boxplot a list (or a 2d array) containing each array you want to plot.
import numpy as np
import pylab as plt
totfigs = 5
plt.figure()
plt.hold = True
boxes=[]
for i in np.arange(totfigs):
x = np.random.random(50)
boxes.append(x)
plt.boxplot(boxes,vert=0)
plt.show()
try:
plt.subplot('{0}{1}{2}'.format(totfigs, 1, i+1) # n rows, 1 column
or
plt.subplot('{0}{1}{2}'.format(1, totfigs, i+1)) # 1 row, n columns
from the docstring:
subplot(*args, **kwargs)
Create a subplot command, creating axes with::
subplot(numRows, numCols, plotNum)
where plotNum = 1 is the first plot number and increasing plotNums
fill rows first. max(plotNum) == numRows * numCols
if you want them all together, shift them conveniently. As an example with a constant shift:
for i in np.arange(totfigs):
x = np.random.random(50)
plt.boxplot(x+(i*2),vert=0)