Finding certain plotting style - python

I am looking for a plotting function in matplotlib that plots the y-values as bars just like in an autocorrelogram but for a general function. Is there a method to do this in matplotlib or do I have to write my own function?

You could use stem
import numpy as np; np.random.seed(21)
import matplotlib.pyplot as plt
x = np.linspace(5,75)
y = np.random.randn(len(x))
plt.stem(x,y, linefmt="k", markerfmt="none", basefmt="C0", use_line_collection=True)
plt.show()

Related

how to plot two functions as a same function with same x axis?

I have written a code that produces standing waves. I am getting the standing waves but the forward wave and backward wave that I have created are two different functions that's why different colors are appearing. now I want to write the forward and backward waves in a single function?
the code is
import numpy as np
import matplotlib.pyplot as plt
x=linspace(0,4*np.pi,10001)
y=np.sin(x)
yn=(-y)
plt.plot(x,y)
plt.plot(x,-y)
how to modify it and plot it as a single function.
I guess on of the efficient ways to achieve it
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0,4*np.pi,10001)
y=np.sin(x)
plt.plot(x,y,'b-', x, -y, 'b-')
Hopefully, it helps
Welcome to SO :)
A function that contains two functions means f(x)=>(y, -y), and this is illegal according to plot function documentation and would cause x and y must have same first dimension error and moreover it is against the theoretical definition of the function itself! But if you are into unifying the graph colors why don't you set it manually?
import numpy as np
from numpy import *
import matplotlib.pyplot as plt
x=linspace(0,4*np.pi,10001)
y=np.sin(x)
yn=(-y)
plt.plot(x,y, color='red')
plt.plot(x,-y, color='red')

Scaling down a plot when using matplotlib

I've been trying to plot a graph of Epoch vs Accuracy and val_accuracy from a train log I have generated. Whenever I try to plot it, the y-axis starts from 0.93 rather than it being in 0, 0.1 ,0.2... intervals. I'm new at using matplotlib or any plot function.
Here's the code for it:
import pandas as pd
import matplotlib.pyplot as plt
acc = pd.read_csv("train_log", sep = ',')
acc.plot("epoch", ["accuracy","val_accuracy"])
plt.savefig('acc' , dpi = 300)
I'm open to suggestion in complete different ways to do this.
Picture of plot :
[1]: https://i.stack.imgur.com/lgg0W.png
This has already been discussed here. There are a couple of different ways you can do this (using plt.ylim() or making a new variable like axes and then axes.set_ylim()), but the easiest is to use the set_ylim function as it gives you heaps of other handles to manipulate the plot. You can also handle the x axis values using the set_xlim function.
You can use the set_ylim([ymin, ymax]) as follows:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0,5)
y = np.arange(5,10)
axes = plt.gca()
axes.plot(x,y)
axes.set_ylim([0,10])
You can use the plt.ylim() like this:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0,5)
y = np.arange(5,10)
plt.plot(x,y)
plt.ylim([0,10])
This will produce the same plot.
You need to set the lower/bottom limit using ylim().
For details please refer:
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.ylim.html

Matplotlib, 3D logaxis, incomplete figure

I am playing with matplotlib, I would like to have a 3d figure with logarithmic axis. I was trying some code, like the one below, but I can only see part of the figure at a time, if I try to move it, I can see other parts, but, not complete.
Does anyone have any idea how to make a 3D plot with log axis?
I can see the 3D image if the axis are linear, but as soon as I change to "log", I can only see part of it.
import matplotlib as mpl
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
data=np.array([[1,10,100],[10,1,1],[2,20,82]])
fig=plt.figure()
ax=Axes3D(fig)
#ax.set_xlim3d(0.1,15)
#ax.set_ylim3d(0.1,15)
#ax.set_zlim3d(0.1,15)
ax.xaxis.set_scale('log')
ax.yaxis.set_scale('log')
ax.zaxis.set_scale('log')
ax.scatter(data[:,0],data[:,1],data[:,2])
plt.show()
I updated matplotlib to 1.3.1, and now I can see the full figure. Now, I think the axis are not in a log scale. I made a plot in matplotlib and the same plot with gnuplot , and it can be seen that the distances between every power of 10, are comlpetely different.
The 3d scatter plot requires x,y,z arguments: if you are trying to plot z data[:,2] (3 points) function of x data[:,0] and y data[:,1], you will see 3 points when the xlim3d,ylim3d,zlim3d are set correctly. This can be done by setting the them to min() and max() of each x,y,z value:
import matplotlib as mpl
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
data=np.array([[1,10,100],[10,1,1],[2,20,82]])
fig=plt.figure()
ax=Axes3D(fig)
ax.set_xlim3d(data[:,0].min(),data[:,0].max())
ax.set_ylim3d(data[:,1].min(),data[:,1].max())
ax.set_zlim3d(data[:,2].min(),data[:,2].max())
ax.xaxis.set_scale('log')
ax.yaxis.set_scale('log')
ax.zaxis.set_scale('log')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.scatter(data[:,0],data[:,1],data[:,2])
plt.show()
Now if you wanted to plot the data array in 3d manner, 9 points in this case, you would need the respective x and y axis. This can be done with np.meshgrid(). In this example I have set x, y equidistant [1,2,3].
import matplotlib as mpl
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
data=np.array([[1,10,100],[10,1,1],[2,20,82]])
datax=np.array([1,2,3])
datay=np.array([1,2,3])
dataxM,datayM = np.meshgrid(datax, datay)
fig=plt.figure()
ax=Axes3D(fig)
ax.set_xlim3d(datax.min(),datax.max())
ax.set_ylim3d(datay.min(),datay.max())
ax.set_zlim3d(data.min(),data.max())
ax.xaxis.set_scale('log')
ax.yaxis.set_scale('log')
ax.zaxis.set_scale('log')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.scatter(dataxM,datayM,data)
plt.show()

Filling region between curve and x-axis in Python using Matplotlib

I am trying to simply fill the area under the curve of a plot in Python using MatPlotLib.
Here is my SSCCE:
import json
import pprint
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791]
x = np.arange(len(y))
fig2, ax2 = plt.subplots()
ax2.fill(x, y)
plt.savefig('picForWeb.png')
plt.show()
The attached picture shows the output produced.
Does anyone know why Python is not filling the entire area in between the x-axis and the curve?
I've done Google and StackOverflow searches, but could not find a similar example. Intuitively it seems that it should fill the entire area under the curve.
I usually use the fill_between function for these kinds of plots. Try something like this instead:
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791]
x = np.arange(len(y))
fig, (ax1) = plt.subplots(1,1);
ax1.fill_between(x, 0, y)
plt.show()
See more examples here.
If you want to use this on a pd.DataFrame use this:
df.abs().interpolate().plot.area(grid=1, linewidth=0.5)
interpolate() is optional.
plt.fill assumes that you have a closed shape to fill - interestingly if you add a final 0 to your data you get a much more sensible looking plot.
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791,0]
x = np.arange(len(y))
fig2, ax2 = plt.subplots()
ax2.fill(x, y)
plt.savefig('picForWeb.png')
plt.show()
Results in:
Hope this helps to explain your odd plot.

PyLab: Plotting axes to log scale, but labelling specific points on the axes

Basically, I'm doing scalability analysis, so I'm working with numbers like 2,4,8,16,32... etc and the only way graphs look rational is using a log scale.
But instead of the usual 10^1, 10^2, etc labelling, I want to have these datapoints (2,4,8...) indicated on the axes
Any ideas?
There's more than one way to do it, depending on how flexible/fancy you want to be.
The simplest way is just to do something like this:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
x = np.exp2(np.arange(10))
plt.semilogy(x)
plt.yticks(x, x)
# Turn y-axis minor ticks off
plt.gca().yaxis.set_minor_locator(mpl.ticker.NullLocator())
plt.show()
If you want to do it in a more flexible manner, then perhaps you might use something like this:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
x = np.exp2(np.arange(10))
fig = plt.figure()
ax = fig.add_subplot(111)
ax.semilogy(x)
ax.yaxis.get_major_locator().base(2)
ax.yaxis.get_minor_locator().base(2)
# This will place 1 minor tick halfway (in linear space) between major ticks
# (in general, use np.linspace(1, 2.0001, numticks-2))
ax.yaxis.get_minor_locator().subs([1.5])
ax.yaxis.get_major_formatter().base(2)
plt.show()
Or something like this:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
x = np.exp2(np.arange(10))
fig = plt.figure()
ax = fig.add_subplot(111)
ax.semilogy(x)
ax.yaxis.get_major_locator().base(2)
ax.yaxis.get_minor_locator().base(2)
ax.yaxis.get_minor_locator().subs([1.5])
# This is the only difference from the last snippet, uses "regular" numbers.
ax.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter())
plt.show()

Categories