Data points cut off when plotting - python

I have a plot where the data points has been cut off, as can be seen in the picture. I need to fix this issue by showing clearly the data points, I have already tried to use ax.margins from previous questions , but it does not change anything on my plot. The following is the code I am using. I guess the ylim might be raising this issue, but if I don't use ylim all my data stays very near to zero axis.
def doscatterplot(xcoord,ycoord,labellist,ax=None):
ax = ax
ax.scatter(xcoord, ycoord,label=labellist)
# ax.xaxis.set_major_formatter(mtick.FormatStrFormatter('%.2f'))
ax.legend()
ax.margins(0.1,y=0.7)
ax.set_ylim(min(ycoord),max(ycoord))
ax.ticklabel_format(axis='y',style='sci',scilimits=(-3,-4))
ax.axhline(y=0, color='g')
ax.axvline(x=0, color='g')
ax.set_ylabel('Transversal Resistance [\u03A9]')
ax.set_xlabel('HCools [T]')
ax.set_title('Transversal Resistance [\u03A9] vs HCools [T]' )
return

What I meant in my comment is to add this extra line of code:
dy = (max(ycoord) - min(ycoord))/20
to add a little extra space above and below your plotted data (in this case, the 20th part of the range of your data). Change the old line for this one and it should work as you want:
ax.set_ylim(min(ycoord) - dy, max(ycoord) + dy)
Also, note that you can write greek symbols without resorting to unicode language, try for example
ax.set_ylabel(r'Transversal Resistance [$\Omega$]')
You can see more information here.

Related

MatPlotLib not displaying both graphs when sharing X axes

This is a bit of an odd problem I've encountered. I'm trying to read data from a CSV file in Python, and have the two resulting lines be inside of the same box, with different scales so they're both clear to read.
The CSV file looks like this:
Date,difference,current
11/19/20, 0, 606771
11/20/20, 14612, 621383
and the code looks like this:
data = pd.read_csv('data.csv')
time = data['Time']
ycurr = data['current']
ydif = data['difference']
fig, ax = plt.subplots()
line1, = ax.plot(time, ycurr, label='Current total')
line1.set_dashes([2, 2, 10, 2]) # 2pt line, 2pt break, 10pt line, 2pt break
line2, = ax.twinx().plot(time, ydif, dashes=[6, 2], label='Difference')
ax.legend()
plt.show()
I can display the graphs with the X-axis having Date values and Y-axis having difference values or current values just fine.
However, when I attempt to use subplots() and use the twinx() attribute with the second line, I can only see one of two lines.
I initially thought this might be a formatting issue in my code, so I updated the code to have the second line be ax2 = ax1.twin(x) and call upon the second line using this, but the result stayed the same. I suspect that this might be an issue with reading in the CSV data? I tried to do read in x = np.linspace(0, 10, 500) y = np.sin(x) y2 = np.sin(x-0.05) instead and that worked:
Everything is working as expected but probably not how you want it to work!
So each line only consists of two data points which in the end will give you a linear curve. Both of these curves share the same x-coordinates while the y-axis is scaled for each plot. And here comes the problem, both axes are scaled to display the data in the same way. This means, the curves lie perfectly on top of each other. It is difficult to see because both lines are dashed.
You can see what is going on by changing the colors of the line. For example add color='C1' to one of the curves.
By the way, what do you want to show with your plot? A curve consisting of two data points mostly doesn't show much and you are better of if you just show their values directly instead.

Scrolling plot using matplotlib "smears" when updating

The application I'm coding for requires a real time plot of incoming data that is being stored long term in an excel spreadsheet. So the real time graph displays the 25 most recent data points.
The problem comes when the plot has to shift in the newest data point and shift out the oldest point. When I do this, the graph "smears" as shown here:
I then began to use plt.cla(), but this causes me to lose all formatting in my plots, such as the title, axes, etc. Is there any way for me to update my graph, but keep my graph formatting?
Here's an example after plt.cla():
.
And here's basically how I'm updating my graphs within a larger loop:
if data_point_index < max_data_points:
y_data[data_point_index] = measurement
plt.plot(x_data[:data_point_index + 1], y_data[:data_point_index + 1], 'or--')
else:
plt.cla()
y_data[0:max_data_points - 1] = y_data[1:max_data_points]
y_data[max_data_points - 1] = measurement
plt.plot(x_data, y_data, 'or--')
plt.pause(0.00001)
I know I can just re-add axis labels and such, but I feel like there should be a more eloquent way to do so and it is somewhat of a hassle as there can be multiple sub-plots and reformatting the figure takes a non-trivial amount of time.
Rather than plt.cla(), which as you have found out clears everything on the axes, you could just remove the last line plotted, which will leave you labels and formatting intact.
The Axes instance has an attribute lines, which stores all the lines currently plotted on the axes. To remove the last line plotted, we can access the current axes using plt.gca(), and then pop() from the list of lines on the axes.
else:
plt.gca().lines.pop()
y_data[0:max_data_points - 1] = y_data[1:max_data_points]
y_data[max_data_points - 1] = measurement
plt.plot(x_data, y_data, 'or--')

Down arrow symbol in matplotlib

I would like to create a plot where some of the points have a downward pointing arrow (see image below). In Astronomy this illustrates that the true value is actually lower than what's measured.Note that only some of the points have this symbol.
I would like to know how I can create such symbols in matplotlib. Are there downward arrow symbols that I can use?
Thanks for your help in advance!
Sure.
When calling matplotlibs plot function, set a marker
If stuff like caretdown doesn't work for you, you can create your own marker by passing a list of (x,y) pairs, which are passed to a Path artist. x/y are 0…1 normalized coordinates that are scaled to the set marker size.
You can also pass an existing Path instance as a marker, which allows even more flexibility.
As mentioned by tom10 in the comments you can also pass a string in the form of $…$ as a marker, where … is arbitrary text, including Unicode characters, if your font supports it (should be the case these days). Downwards arrow in Unicode: ↓ (or \u2193, resulting in $\u2193$ as the marker. Note that this must be a unicode string in Python 2.x [prepend u]). Unicode Block Arrows # Wikipedia
You could also try passing a Arrow instance as marker, but I'm not sure whether that works.
The answer to my question was answered by Tom0 and Dom0. However, I just want to help the newbies like me understand how to plot those arrows. Below is the code that I found and edited to include what is said in the above example and suggestion. I hope this will help people quickly understand. I am not seeking any points.
If you like the example, please thank Dom0 and not me. :-)
import numpy as np
import matplotlib.pyplot as plt
symbols = [u'\u2193'] # this helps you get the symbol
x = np.arange(10.)
y = np.exp(-x/2.)
plt.figure()
for i, symbol in enumerate(symbols):
y2 = np.exp(-x/2.)
plt.plot(x, y, 'o') # plotting with field circles
plt.plot(x, y2, 'g') # plotting with green line
for x0, y0 in zip(x, y2):
plt.text(x0, y0, symbol, fontname='STIXGeneral', size=30, va='center', ha='center', clip_on=True)
plt.show()
Matplotlib supports a subset of Latex in a built-in module called mathtext. The main purpose is to properly render mathematical and scientific equations and symbols, but there's also large number of arrow symbols that can easily be used in your graphs. The following link is to the tutorial for writing math expressions. Near the bottom of the page is a list of about 80 arrow symbols.
https://matplotlib.org/users/mathtext.html#mathtext-tutorial
Examples:
plt.plot(x, y, marker=r'$\uparrow$')
plt.plot(x, y, marker=r'$\downarrow$')
Take a look at this example code: http://matplotlib.org/examples/pylab_examples/errorbar_limits.html
OR:
Another easy way to do this:
arrow = u'$\u2193$'
ax.plot(x, y, linestyle='none', marker=arrow, markersize=10)

adding extra axis ticks using matplotlib

I have a simple plot code as
plt.plot(x,y)
plt.show()
I want to add some extra ticks on the x-axis in addition to the current ones, let's say at
extraticks=[2.1, 3, 7.6]
As you see I do not have a pattern for ticks so I do not want to increase the tick frequency for the whole axis; just keep the original ones and add those extras...
Is it possible, at all?
Regards
Yes, you can try something like:
plt.xticks(list(plt.xticks()[0]) + extraticks)
The function to use is xticks(). When called without arguments, it returns the current ticks. Calling it with arguments, you can set the tick positions and, optionally, labels.
For the sake of completeness, I would like to give the OO version of #Lev-Levitsky's great answer:
lines = plt.plot(x,y)
ax = lines[0].axes
ax.set_xticks(list(ax.get_xticks()) + extraticks)
Here we use the Axes object extracted from the Lines2D sequence returned by plot. Normally if you are using the OO interface you would already have a reference to the Axes up front and you would call plot on that instead of on pyplot.
Corner Caveat
If for some reason you have modified your axis limits (e.g, by programatically zooming in to a portion of the data), you will need to restore them after this operation:
lim = ax.get_xlim()
ax.set_xticks(list(ax.get_xticks()) + extraticks)
ax.set_xlim(lim)
Otherwise, the plot will make the x-axis show all the available ticks on the axis.

Matplotlib/pyplot: How to enforce axis range?

I would like to draw a standard 2D line graph with pylot, but force the axes' values to be between 0 and 600 on the x, and 10k and 20k on the y. Let me go with an example...
import pylab as p
p.title(save_file)
p.axis([0.0,600.0,1000000.0,2000000.0])
#define keys and items elsewhere..
p.plot(keys,items)
p.savefig(save_file, dpi=100)
However, the axes still adjust to the size of the data. I'm interpreting the effect of p.axis to be setting what the max and min could be, not enforcing them to be the max or min. The same happens when I try to use p.xlim() etc.
Any thoughts?
Thanks.
Calling p.plot after setting the limits is why it is rescaling. You are correct in that turning autoscaling off will get the right answer, but so will calling xlim() or ylim() after your plot command.
I use this quite a lot to invert the x axis, I work in astronomy and we use a magnitude system which is backwards (ie. brighter stars have a smaller magnitude) so I usually swap the limits with
lims = xlim()
xlim([lims[1], lims[0]])
To answer my own question, the trick is to turn auto scaling off...
p.axis([0.0,600.0, 10000.0,20000.0])
ax = p.gca()
ax.set_autoscale_on(False)
I tried all of those above answers, and I then summarized a pipeline of how to draw the fixed-axes image. It applied both to show function and savefig function.
before you plot:
fig = pylab.figure()
ax = fig.gca()
ax.set_autoscale_on(False)
This is to request an ax which is subplot(1,1,1).
During the plot:
ax.plot('You plot argument') # Put inside your argument, like ax.plot(x,y,label='test')
ax.axis('The list of range') # Put in side your range [xmin,xmax,ymin,ymax], like ax.axis([-5,5,-5,200])
After the plot:
To show the image :
fig.show()
To save the figure :
fig.savefig('the name of your figure')
I find out that put axis at the front of the code won't work even though I have set autoscale_on to False.
I used this code to create a series of animation. And below is the example of combing multiple fixed axes images into an animation.
Try putting the call to axis after all plotting commands.

Categories

Resources