I'm trying to simplify the look of a graph of mine. To this extent, I would like to set ticks only on definite points.
The 'native' plot, out of a df.groupby.max().plot() operation looks like this:
I don't like the fact that my data starts at 0.3 and ends at 0.6, but the graph is somewhat adding real estate there. To have the plot limited to the numbers I want, I do:
ax1.set_xlim(0.3,0.6)
Which however adds a series of intermediate points I wouldn't like to have:
Now, for some reason, halfway points appear. Note that they do not belong to the measured data.
I've then tried the recipes found - among other places - here
ax1.set_xticks = np.arange(0.3,0.6,0.1)
--> no change
ax1.xaxis.set_tick_params(which='minor',bottom=False)
--> no change
ax1.minorticks_off()
--> no change
I've run out of options and I'm not sure what I'm doing wrong here, any help appreciated.
OK,
thanks to #DavidG's hint I found the issue. It's maybe not subtle but worth mentioning. I can remove the whole thing if this turns out to be too trivial.
The issue was created by this wrong call to the ax.set_xticks() function:
ax1.set_xticks = np.arange(0.3,0.6,0.1)
Although I cited the place where I took this approach, I actually managed to implement it wrongly. The right way would have been:
ax1.set_xticks(np.arange(0.3,0.6,0.1))
So, actually, I wasn't seeing any change in the plot because I wasn't calling the function correctly.
But there's more.
My code was actually assigning the (name?) ax1.set_xticks to an np.array, so that when trying to then implement the correct syntax, I kept getting an error:
ax1.set_xticks([0.3,0.4,0.5,0.6])
Traceback (most recent call last):
File "<ipython-input-93-df3b8935eb28>", line 1, in <module>
ax1.set_xticks([0.3,0.4,0.5,0.6])
TypeError: 'numpy.ndarray' object is not callable
Even with a simple list, I was getting the error. This is because I had assigned the name ax1.set_xticks to, indeed, an np.array object.
Once reset the variable space and properly called the function, everything ran smoothly.
Related
Can someone please explain where I went wrong? I used the same code for a different problem where i had to create arrays from the given specifications, but i dont understand where this code went wrong.
I think your problem is that you haven't quite got straight what your variables mean.
In the function definition, you use Xp to mean a single value.
You also define it as a single value.
However just before you call the function, you treat it as though it was a list:
[ F(X,Y,i) for i in Xp ]
One fix would be to set Xp = [302], not 302.
Preventing future similar errors
Even better would be to use a more mnemonic variable name, such as Xp_list, so that you don't fall into a similar trap in future. In my code I would typically call those variables:
x_list
y_list
xp_list
Or
xs
ys
xps
I feel guilty for asking question I can not properly name because I can not name the pattern used in the code.
There is a code on github I'm trying to understand and failing to do so.
https://github.com/kivy-garden/speedmeter/blob/master/kivy_garden/speedmeter/init.py
Pattern I don't understand is in lines 128,129 and 181, 182 and many other places.
Big picture is.
There a class
class MyClassName(Widget):
there are methods e.g.
def _draw_this_and_that(self):
self._someName.clear()
add = self._someName.add
add(Color(rgba=get_color_from_hex(color)))
This "_someName" found in whole code only in those 2 places as my code sample.
I understand that
add = self._someName.add
creates function "add" but why that is needed? why not calling
self._someName.add
instead?
I guess that
self._someName.clear()
does erase whatever was added to "_someName", right?
I completely do not understand how
add(Color(rgba=get_color_from_hex(color)))
does it job (but it does) and then whatever is drawn will be with that color.
Do I guess it right that if I need to change color (if some condition met) then I could just add different color?
add(Color(rgba=get_color_from_hex(different_color)))
and don't stress that adding will cause memory leak because
self._someName.clear()
will take care of it?
I never seen such pattern. I'd be very happy if someone could explain how it works and why.
Thank you in advance!
The _somenameIG are canvas instruction groups that are created in the __init__() method:
add = self.canvas.add
for instructionGroupName in _ig:
ig = InstructionGroup()
setattr(self, '_%sIG' % instructionGroupName, ig)
add(ig)
So, the self._someName.clear() is clearing a canvas instruction group, and the add() method adds instructions to the group.
In addition to the other answer I would like to address the following:
Pattern I don't understand is in lines 128,129 and...
According to its documentation the attr. sectors in line 130 is a list of alternating values and colors a copy of which is stored locally by l and then the color value(s) is(are) passed to the InstructionGroup. Since it is used as a redrawing mechanism, the instruction groups are removed from canvas by the method clear before drawing again.
creates function "add" but why that is needed? why not calling...
This is done mainly to prevent the re-evaluation process.
I'm trying to make an animation with matplotlib, in this case a 3D scatter plot. I'm hitting a problem that I absolutely always hit when I try to do this, which is that I don't know what arguments I should pass to set_data, and I don't know how to find out. In this case, it apparently expects two arguments, despite it being a 3d plot.
Since I've experienced related problems often, rather than asking about the specifics of the particular plot I'm trying to animate, I will ask the general question: given an element of a MatPlotLib plot, how can I determine what arguments its set_data method expects, either by interrogating it, or by knowing where it's documented?
From an example for an Animated 3D random walk from the MatPlotLib documentation:
def update_lines(num, dataLines, lines):
for line, data in zip(lines, dataLines):
# NOTE: there is no .set_data() for 3 dim data...
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2, :num])
return lines
So as confusing as you discovered it is set_data by itself is not meant for 3D data, as well as according to the docs it accepts:
2D array (rows are x, y) or two 1D arrays
Looking more at this example we can see that the set_3d_properties has been used altogether.
This whole update_lines was set as a callback parameter for animation.FuncAnimation.
Usually to find the documentation you can either search it up online (e.g doc for set_data) or from a python prompt you can use the help function, which will show you the docstring of the object (can be used on a module/function/class etc) if it has any.
For example if you want to know what the datetime.datetime.now does (I dont have mathplotlib install to use it on it):
>>> import datetime
>>> help(datetime.datetime.now)
Help on built-in function now:
now(tz=None) method of builtins.type instance
Returns new datetime object representing current time local to tz.
tz
Timezone object.
If no tz is specified, uses local timezone.
I'm working on my Computer Graphics homework. Since we're allowed to choose the PL we want, I decided this would be a good occasion to learn some Python, but I ran into some trouble, eventually.
In one module I have some functions like this:
def function1 (a, b, matrix):
...
function2 (matrix)
def function2(matrix):
...
function3(x,y,matrix):
def function3(x,y,matrix):
...
matrix[x][y] = something
Now, from a different module, I call function1. It should then call function2 passing it the matrix, which should in turn call function3 passing it the matrix. However, I get a list assignment index out of range when attempting to access matrix[x][y.
If I try to call them on a matrix from the same module, it will work, so I thought that the functions might not realize they are receiving a matrix. I changed the function definitions to something like
function2(matrix = [[]])
but I still get the same error. I'm kind of stuck.
Sorry everyone, you were right.
There was this one pixel in a 500x500, which was actually at matrix[249][500].
When I made the checks, I checked if they're <=500 instead of <500, don't know why.
Thanks, I was pretty sure I was screwing something else up, especially after I added my (faulty) tests, since this is my first time writing python.
In my recent project I have the problem, that some values are often misinterpreted. For instance I calculate a wave as a sum of two waves (for which I need two amplitudes and two phase shifts), and then sample it at 4 points. I pass these tuples of four values to different functions, but sometimes I made the mistake to pass wave parameters instead of sample points.
These errors are hard to find, because all the calculations work without any error, but the values are totally meaningless in this context and so the results are just wrong.
What I want now is some kind of semantic type. I want to state that the one function returns sample points and the other function awaits sample points, and that I can do nothing that would conflict this declarations without immediately getting an error.
Is there any way to do this in python?
I would recommend implementing specific data types to be able to distinguish between different kind of information with the same structure.
You can simply subclass list for example and then do some type checking at runtime within your functions:
class WaveParameter(list):
pass
class Point(list):
pass
# you can use them just like lists
point = Point([1, 2, 3, 4])
wp = WaveParameter([5, 6])
# of course all methods from list are inherited
wp.append(7)
wp.append(8)
# let's check them
print(point)
print(wp)
# type checking examples
print isinstance(point, Point)
print isinstance(wp, Point)
print isinstance(point, WaveParameter)
print isinstance(wp, WaveParameter)
So you can include this kind of type checking in your functions, to make sure the correct kind of data was passed to it:
def example_function_with_waveparameter(data):
if not isinstance(data, WaveParameter):
log.error("received wrong parameter type (%s instead WaveParameter)" %
type(data))
# and then do the stuff
or simply assert:
def example_function_with_waveparameter(data):
assert(isinstance(data, WaveParameter))
Pyhon's notion of a "semantic type" is called a class, but as mentioned, Python is dynamically typed so even using custom classes instead of tuples you won't get any compile-time error - at best you'll get runtime errors if your classes are designed in such a way that trying to use one instead of the other will fail.
Now classes are not just about data, they are about behaviour too, so if you have functions that do waveform-specific computations these functions would probably become methods of the Waveform class, and idem for the Point part, and this might be enough to avoid logical errors like passing a "waveform" tuple to a function expecting a "point" tuple.
To make a long story short: if you want a statically typed functional language, Python is not the right tool (Haskell might be a better choice). If you really want / have to use Python, try using classes and methods instead of tuples and functions, it still won't detect type errors at compile-time but chances are you'll have less type errors AND that these type errors will be detected at runtime instead of producing wrong results.