Python matplotlib graph problem - python

import matplotlib
import matplotlib.pyplot as plt
import pylab as PL
matplotlib.rcParams['axes.unicode_minus'] = False
fig = plt.figure()
ax = fig.add_subplot(111)
PL.loglog(a, b,'o')
ax.set_title('Graph Example')
plt.show()
1) This displays the graph with points on the plot. Is there a way to join these points with a smooth curve.
2) I want to draw more than one plot in the same graph(i.e. for a different set of values of lists a and b) . How do I do that? I want to represent points of each graph with a different symbol(cross,square,circle) or color.

See #Ber's comment
Simply call PL.loglog multiple times.

Related

Matplotlib: How to recreate `6 petal` polar diagram

For an assignment, I have to recreate the following plot (including all labels and ticks):
This is what I have tried so far with my code
import numpy as np
import matplotlib.pyplot as plt
nmax=101 # choose a high number to "smooth out" lines in plots
x = np.linspace(0,20,nmax) # create an array x
y_br = np.sin(3*x) # y for the bottom right subplot
fig = plt.figure()
ax4 = plt.subplot(224, projection = 'polar')
ax4.plot(x, y_br, 'tab:blue')
But if you were to run this yourself, this does not replicate the plot. What function could be used here and how can tick marks be changed in polar plots? Thanks in advance?

Fix location of stippling for subplots

I have been trying to stipple contour plots to show locations where values are statistically significant. However, when I do this in subplots where the significance is the same, the stippling looks different based on the random location of the filled stipples. I have reproduced the problem below. Is there a way to fix the location of the stipples so that they look the same when plotted? Or is there a better way to stipple plots?
These 2 subplots are plotting the exact same data, but the stipples look different.
import numpy as np
from matplotlib import pyplot as plt
#Create some random data
x = np.arange(0,100,1)
x,y = np.meshgrid(x,x)
stipp = 10*np.random.rand(len(x),len(x))
fig =plt.figure(figsize=(12,8))
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
#Plot stippling
ax1.contourf(x,y,stipp,[0,4],colors='none',hatches='.')
ax2.contourf(x,y,stipp,[0,4],colors='none',hatches='.')
plt.show()
So in case anyone wants to know, the best way to stipple multiple subplots with similar statistical significance is to use a scatter plot as recommended above instead of contouring. Just make sure to sample the data sparingly so you don't have a high density of dots next to each other.
import numpy as np
from matplotlib import pyplot as plt
#Create some random data
x = np.arange(0,100,1)
x,y = np.meshgrid(x,x)
stipp = 10*np.random.rand(len(x),len(x))
fig =plt.figure(figsize=(12,8))
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
#Plot stippling
ax1.scatter(x[(stipp<=4) & (stipp>=0)][::5],y[(stipp<=4) & (stipp>=0)][::5])
ax2.scatter(x[(stipp<=4) & (stipp>=0)][::5],y[(stipp<=4) & (stipp>=0)][::5])
plt.show()

Python, Matplotlib: Suptitle with arbitrary number of vertical figures

I have a website that produces (depending on available data stations running) an arbitrary number of plots (as an image), that are vertically stacked over one another. An example is the following:
The problem is that depending on the number of vertical plots, the suptitle (top title) goes to a different position. Check the following examples of 5 and 10 plots:
5 plots:
And here's 10 plots:
So for every number of plots, I get a different result. Using fig.tight_layout() didn't help.
What I need is to have the bottom of my text at a certain distance from the top of the plots. Is there a general answer to this problem?
I created some minimal working code that has the number of plots parametrized. Please check it out if you would like to reproduce this problem.
import datetime
import random
import matplotlib
matplotlib.use('Agg') # Force matplotlib not to use any Xwindows backend.
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.image as mpimg
import matplotlib.gridspec as gridspec
import numpy as np
random.seed(datetime.datetime.now())
#initial parameters
numOfPlots = 2
dataLen = 100
randomRange = 10*dataLen
dpiVal = 180
#create data
xData = list(range(dataLen) for x in range(numOfPlots))
yData = list(random.sample(range(randomRange), dataLen) for x in range(numOfPlots))
#matplotlib initialize plot
gs = gridspec.GridSpec(numOfPlots,1)
plt.cla()
plt.clf()
fig = plt.figure()
ax = None
for i in list(range(numOfPlots)):
if i == 0:
ax = fig.add_subplot(gs[i])
else:
ax = fig.add_subplot(gs[i],sharex=ax)
ax.plot(xData[i], yData[i])
labelSize = 10
ax.set_ylabel("Hi there",size=8)
ax.get_yaxis().set_label_coords(-0.07,0.5)
plt.yticks(size=8)
plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0),useOffset=True)
plt.subplots_adjust(hspace = 0.3)
if i == numOfPlots-1:
plt.xticks(rotation=0,size=7)
max_xticks = 10
xloc = plt.MaxNLocator(max_xticks)
ax.xaxis.set_major_locator(xloc)
ax=plt.gca()
else:
plt.tick_params(
axis='x', # changes apply to the x-axis
labelbottom='off') # labels along the bottom edge are off
ax_right = ax.twinx()
ax_right.yaxis.set_ticks_position('right')
ax_right.set_ylabel("Nice to see you!",size=labelSize)
ax_right.get_yaxis().set_ticks([])
#the following sets the size and the aspect ratio of the plot
fig.set_size_inches(10, 1.8*numOfPlots)
fig.suptitle("Hi there, this is the first line\nAnd this is the second!!!")
fig.savefig("img_"+str(numOfPlots)+".png",bbox_inches='tight',dpi=dpiVal)
I suggest trying something manual: adding text annotation with position in units of the figure relative coordinates.
Consider these two dummy examples:
hf,ax = plt.subplots(nrows=3)
hf.text(0.5,0.92,
"Hi there, this is the first line\nAnd this is the second!!!",
horizontalalignment='center')
hf,ax = plt.subplots(nrows=7)
hf.text(0.5,0.92,
"Hi there, this is the first line\nAnd this is the second!!!",
horizontalalignment='center')
The result has the "suptitle" located in the exact same position:

python + matplotlib: barh plot show incomplete YTick labels - how to dynamically move the plot area to the right to fit the given YTickLabels?

I'm using matplotlib to plot a barh plot to a file. Unfortunate, the YTickLaels are a bit too long and the plot area won't move to the right automatically. Is there a way to move the plot area to the right automatically so I won't have problems with incomplete YTickLabels?
The code I use is the following:
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
D = {u'Label1':26, u'Label2 is longer than others': 17, u'Label3 is not so short either':30}
fig = plt.figure(figsize=(5.5,3),dpi=300)
ax = fig.add_subplot(111)
ax.grid(True,which='both')
bar = ax.barh(range(1,len(D)+1,1),D.values(),0.4,align='center')
plt.yticks(range(1,len(D)+1,1), D.keys(), size='small')
fig.savefig('D_bar.png')
Here is the output:
How can I fix this? Thanks
Actually, there is an automatic way of doing this now: tight_layout.
In your case:
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
D = {u'Label1':26, u'Label2 is longer than others': 17,
u'Label3 is not so short either':30}
fig = plt.figure(figsize=(5.5,3),dpi=300)
ax = fig.add_subplot(111)
ax.grid(True,which='both')
bar = ax.barh(range(1,len(D)+1,1),D.values(),0.4,align='center')
plt.yticks(range(1,len(D)+1,1), D.keys(), size='small')
fig.tight_layout() # <---- ADD THIS
fig.savefig('D_bar.png')
According to matplotlib mailing list, there is no automatic way of doing this. However, you can manually ajdust subplot padding by using figure.subplots_adjust method. Placing fig.subplots_adjust(left = 0.4) after ax = fig.add_subplot(111) in your code yields following result:

Enlarging plot in mplot3D

I'm trying to compose an image with both 2D and 3D plot. so far I've done the following:
import idlsave
import matplotlib
from matplotlib import *
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from matplotlib import rc
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
fig = plt.figure(figsize=(18,5))
ax = fig.add_subplot(1,3,1, projection='3d',azim=-133,elev=14)
l = ax.plot3D(X3D,Y3D,Z3D,lw=2,color='red')
ax.set_xlim3d(-10,10)
ax.set_ylim3d(-10,10)
ax.set_zlim3d(-10,10)
ax.text(-2,-7,-11,'b$_r$ [mT]','x')
ax.text(-5,-1,-11,'b$_p$ [mT]','y')
ax.set_zlabel(r'b$_t$ [mT]')
ax.plot([bEq[0],-bEq[0]],[bEq[1],-bEq[1]],[bEq[2],-bEq[2]],'b--',lw=2)
ax.plot([pLe[0],-pLe[0]],[pLe[1],-pLe[1]],[pLe[2],-pLe[2]],color='black',lw=2)
ax.text(3,12,9.2,'(a)', fontsize=14)
ax = fig.add_subplot(1,3,2)
l = ax.plot(br,bp,'k-',lw=2)
ax.set_xlabel(r'b$_{\lambda_1}$ [mT]')
ax.set_ylabel(r'b$_{\lambda_2}$ [mT]')
ax.set_xlim(-2,6.3)
ax.set_ylim(-5.5,5.5)
ax.plot([0,0],[-5.5,5.5],'k-.')
ax.plot([-2,6.3],[0,0],'k-.')
e=Ellipse((pf[2],pf[3]),2*pf[0],2*pf[1],- pf[4]*57.2958,fc='none',lw=2,ls='dashed',ec='red')
ax.add_artist(e)
ax.text(-1,4, '(b)', fontsize=14)
ax = fig.add_subplot(1,3,3)
ax.plot(-bxDip,-byDip,'b-',lw=2,label='$\mathcal{D}$')
ax.plot(-bxMon,-byMon,'r-',lw=2,label='$\mathcal{M}$')
ax.set_xlabel(r'b$_{\lambda_1}$')
ax.set_ylabel(r'b$_{\lambda_2}$')
ax.set_xlim(-4,12)
ax.set_ylim(-6,7)
ax.plot([-4,12],[0,0],'k-.')
ax.plot([0,0],[-6,7],'k-.')
ax.legend(loc='upper right')
ax.text(-3,5.5, '(c)', fontsize=14)
plt.savefig("../pdf_box/fig3.pdf",bbox_inches='tight')
Wit the present code I was able to produce the figure reported here http://img219.imageshack.us/i/fig3e.png/
There are two question which puzzle me.
1) As you can see the 3D plot is smaller than the other two and there is enough white spaces between the subplots to increase the size. How can I do this? i.e. How can I enlarge the size of one subplot, eventually decreasing the other two?
2) I would like to exclude the grey background in the 3D plot.
Any help is very welcomed.
Change ax.dist for the 3D plot. This will cause the rendered graphic to fill more of the subplot area. Here is a similar question. You may find some more info there.
You may also want to adjust the widths of the subplots with respect to each other (increase the width of the 3d plot and shrink the 2D plots. This can be accomplished with subplots_adjust

Categories