plotting an iv-curve with python - python

So I am trying to plot an IV-curve using python, but all I'm getting is a straight, linear line. This may seem like a trivial code, but I just started self teaching myself literally a week a go, so bear with me as I am still learning :)
Here's my code:
import matplotlib.pyplot as plt
xdata = [20,27] # voltage data
ydata = [0.4,0.9] # current data
plt.plot(xdata, ydata)
plt.title(r'IV-curve')
plt.xlabel('Voltage(V)')
plt.ylabel('Current(I)')
plt.show()
A picture of it is shown here: http://imgur.com/a/lxPPo

Probably you can try something like below (change equation to set 'y' based on your requirements):

Related

PyTest Matplotlib Figure Appears on Show

I have a complicated method called plotter() which processes some data and produces a matplotlib plot with several components. Due to its complexity I simply want to test that the plot appears. This will confirm that all of the data is processed reasonably and that something gets shown without any errors being thrown. I am not looking to run an image comparison as that's not currently possible for this project.
My function is too complicated to show here, so the following example could be considered instead.
import matplotlib.pyplot as plt
import numpy as np
def plotter():
x = np.arange(0,10)
y = 2*x
fig = plt.plot(x, y)
plotter()
plt.show()
Is there a way to use PyTest to simply assert that a figure appears? If not then solutions using other test frameworks would also be greatly appreciated.
(For context I am using Python 3.)

Real-time plot in matplotlib - python

I'm trying to get real-time spectrum analyzer type plot in matplotlib. I've got some code working (with help from other posts on StackOverflow) as follows:
import time
import numpy as np
import matplotlib.pyplot as plt
plt.axis([0, 1000, 0, 1])
plt.ion()
plt.show()
i=0
np.zeros([1,500],'float')
lines=plt.plot(y[0])
while 1:
i=i+1
lines.pop(0).remove()
y = np.random.rand(1,100)
lines=plt.plot(y[0])
plt.draw()
The code works and I'm getting what I want, but there is a serious problem. The plot window would freeze after some time. I know the program is still running by inspecting the i variable (I'm running the code in Anaconda/Spyder so I can see the variables). However the plot window would show "Non responding" and if I terminate the python program in Spyder by ctrl+c, the plot window comes back to life and show the latest plot.
I'm out of wits here as how to further debug the issue. Anyone to help?
Thanks
I am not sure that adding plt.pause will entirely solve your issue. It may just take longer before the application crash. The memory used by your application seems to constantly increase over time (even after adding plt.pause). Below are two suggestions that may help you with your current issue:
Instead of removing/recreating the lines artists with each iteration with remove and plot, I would use the same artist throughout the whole animation and simply update its ydata.
I'll use explicit handlers for the axe and figure and call show and draw explicitly on the figure manager and canvas instead of going with implicit calls through pyplot, following the advices given in a post by tcaswell.
Following the above, the code would look something like this:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.axis([0, 100, 0, 1])
y = np.random.rand(100)
lines = ax.plot(y)
fig.canvas.manager.show()
i=0
while 1:
i=i+1
y = np.random.rand(100)
lines[0].set_ydata(y)
fig.canvas.draw()
fig.canvas.flush_events()
I've run the above code for a good 10 minutes and the memory used by the application remained stable the whole time, while the memory used by your current code (without plt.pause) increased by about 30MiB over the same period.
To answer myself, I solved the issue by adding
plt.pause(0.01)
after the
plt.draw()
This probably allows the GUI to finish the drawing and clear the buffer somewhere (my guess) before the new data comes in.
I know I'm late to answer this question, but for your issue you could look into the "joystick" package. It is based on the line.set_data() and canvas.draw() methods, with optional axes re-scaling, hence most probably faster than removing a line and adding a new one. It also allows for interactive text logging or image plotting (in addition to graph plotting).
No need to do your own loops in a separate thread, the package takes care of it, just give the update frequency you wish. Plus the terminal remains available for more monitoring commands while live plotting, which is not possible with a "while True" loop.
See http://www.github.com/ceyzeriat/joystick/ or https://pypi.python.org/pypi/joystick (use pip install joystick to install)
try:
import joystick as jk
import numpy as np
import time
class test(jk.Joystick):
# initialize the infinite loop decorator
_infinite_loop = jk.deco_infinite_loop()
def _init(self, *args, **kwargs):
"""
Function called at initialization, see the doc
"""
self._t0 = time.time() # initialize time
self.xdata = np.array([self._t0]) # time x-axis
self.ydata = np.array([0.0]) # fake data y-axis
# create a graph frame
self.mygraph = self.add_frame(jk.Graph(name="test", size=(500, 500), pos=(50, 50), fmt="go-", xnpts=100, xnptsmax=1000, xylim=(None, None, 0, 1)))
#_infinite_loop(wait_time=0.2)
def _generate_data(self): # function looped every 0.2 second to read or produce data
"""
Loop starting with the simulation start, getting data and
pushing it to the graph every 0.2 seconds
"""
# concatenate data on the time x-axis
self.xdata = jk.core.add_datapoint(self.xdata, time.time(), xnptsmax=self.mygraph.xnptsmax)
# concatenate data on the fake data y-axis
self.ydata = jk.core.add_datapoint(self.ydata, np.random.random(), xnptsmax=self.mygraph.xnptsmax)
self.mygraph.set_xydata(t, self.ydata)
t = test()
t.start()
t.stop()

How do I set the aspect ratio for a plot in Python with Spyder?

I'm brand new to Python, I just switched from Matlab. The distro is Anaconda 2.1.0 and I'm using the Spyder IDE that came with it.
I'm trying to make a scatter plot with equal ratios on the x and y axes, so that this code prints a square figure with the vertices of a regular hexagon plotted inside.
import numpy
import cmath
import matplotlib
coeff = [1,0,0,0,0,0,-1]
x = numpy.roots(coeff)
zeroplot = plot(real(x),imag(x), 'ro')
plt.gca(aspect='equal')
plt.show()
But plt.gca(aspect='equal') returns a blank figure with axes [0,1,0,1], and plt.show() returns nothing.
I think the main problem is that plt.gca(aspect='equal') doesn't just grab the current axis and set its aspect ratio. From the documentation, (help(plt.gca)) it appears to create a new axis if the current one doesn't have the correct aspect ratio, so the immediate fix for this should be to replace plt.gca(aspect='equal') with:
ax = plt.gca()
ax.set_aspect('equal')
I should also mention that I had a little bit of trouble getting your code running because you're using pylab to automatically load numpy and matplotlib functions: I had to change my version to:
import numpy
import cmath
from matplotlib import pyplot as plt
coeff = [1,0,0,0,0,0,-1]
x = numpy.roots(coeff)
zeroplot = plt.plot(numpy.real(x), numpy.imag(x), 'ro')
ax = plt.gca()
ax.set_aspect('equal')
plt.show()
People who are already comfortable with Python don't generally use Pylab, from my experience. In future you might find it hard to get help on things if people don't realise that you're using Pylab or aren't familiar with how it works. I'd recommend disabling it and trying to get used to accessing the functions you need through their respective modules (e.g. using numpy.real instead of just real)

How to separate one graph from the set of multiple graphs on figure

I will not be able to put the code here because it is my assignment.
My program is printing multiple graphs on one plot. Please look at the example figure on the following link: Python: Plot multiple graphs on the same figure
The link above is just an example. That is not my code nor do I have the same program. My topic is completely different. That figure is just for reference.
The line of code I am using to achieve this is: plot(a,b, label=str(meters))
What I want to do is get any one of those graph from those three curves and also plot it separately as if it is the main graph. I am doing all this inside a function, and I have created an array of numbers to loop through these different values to get three different graphs.
Do you mean something like this?
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
a = np.arange(5)
line1, = plt.plot(a, a**2) # a new figure instance is opened automatically
line2, = plt.plot(a, a**3-a)
line3, = plt.plot(a, 4*a-a**2/2.)
fig_handle = plt.figure() # Force a new figure instance to open
plt.plot(a, a**2) # This will replot 'line1', but in this new figure instance.
If not, please update your question, perhaps showing the code you already have.
Note that this is information you could find on the matplotlib pyplot tutorial.

Step by step showing 2D/3D add/remove points

I'm writing some python functions that deals with manipulating sets of 2D/3D coordinates, mostly 2D.
The issue is debugging such code is made difficult just by looking at the points. So I'm looking for some software that could display the points and showing which points have been added/removed after each step. Basically, I'm looking for a turn my algorithm into an animation.
I've seen a few applets online that do things similar what I was looking for, but I lack the graphics/GUI programming skills to write something similar at this point, and I'm not sure it's wise to email the authors of things whose last modified timestamps reads several years ago. I should note I'm not against learning some graphics/GUI programming in the process, but I'd rather not spend more than 1-3 days if it can't be helped, although such links are still appreciated. In this sense, linking to a how-to site for writing such a step-by-step program might be acceptable.
With the matplotlib library it is very easy to get working animations up. Below is a minimal example to work with. The function generate_data can be adapted to your needs:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def generate_data():
X = np.arange(25)
Y = X**2 * np.random.rand(25)
return X,Y
def update(data):
mat[0].set_xdata(data[0])
mat[0].set_ydata(data[1])
return mat
def data_gen():
while True:
yield generate_data()
fig, ax = plt.subplots()
X,Y = generate_data()
mat = ax.plot(X,Y,'o')
ani = animation.FuncAnimation(fig, update, data_gen, interval=500,
save_count=10)
ani.save('animation.mp4')
plt.show()
This example was adapted from a previous answer and modified to show a line plot instead of a colormap.

Categories

Resources