Im working with matplotlib and I want an arrow beside my "axis-legend". But I have no idea how.
In the example, the arrows I want are drawn in red.
thanks
You can generate arrows as shown in your example figure by using the TeX renderer built into matplotlib. Coloring is an option for the whole strings, although generating multiple colors in a single text string is more work.
This will give you the mathematical symbols plus the arrows (I've shown different lengths on each axis label):
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1)
# plot your data here ...
ax.set_xlabel(r'$\rho/\rho_{ref}\;\rightarrow$', color='red')
ax.set_ylabel(r'$\Delta \Theta / \omega \longrightarrow$')
plt.show()
plt.close()
Resulting in:
Partial coloring of text in matplotlib deals with multi-color strings, and this solution describes how to use the latex engine with multiple colors. However, it does not color what is rendered in the interactive graph, so it depends on your exact needs.
More arrows in LaTeX math mode
Related
I'm having trouble creating a colorbar for my plot in Python using matplotlib. I am using a colormap, not to colour all the data that I plot but to extract a colour for a plot based on a value I'm not plotting. Hope this makes sense..
So I'm in a for loop, create a plot every time with a colour based on a certain parameter. Like this (the data is an example to create an mwe, my data is more complicated):
import matplotlib as mpl
from matplotlib import pyplot as plt
import numpy as np
xdata = np.array(range(10))
parameter = [0.5, 0.3, 0.78, 0.21, 0.45] #random parameter example
cmap = mpl.cm.get_cmap('jet')
for i in range(len(parameter)):
clr = cmap(parameter(i))
plt.plot(xdata,xdata**i,c=clr)
plt.show()
Now, what I would want is a colorbar on the side (or actually two, but that's another problem I think) that shows the jet colormap and according values. The values need to be scaled to a new min and max value.
So far I've found the following, but I don't understand it enough to apply it to my own problem:
Getting individual colors from a color map in matplotlib
Which told me how to extract the colour and shows how to create the normalized colormap
Colorbar only
Which should tell me how to add a colorbar without using the plotted data, but I don't understand enough of it. My problem is with the creation of the axes. I don't understand this part if I want to put the colorbar next to my plot. In the example they create a figure with handle fig, but in my case the figure is created when I do plt.imshow(image), since this is what I start with and then I'm plotting over the image. I cannot use the fig.add_axes here.
I hope you can help me out here. It would be great if I could also create a 'reversed' colorbar. So either the colours are in reverse direction, or the values next to the bar.
At any point in the script you can get the figure via fig = plt.gcf() and an axes via ax=plt.gca(). So, adding an axes may be done by plt.gcf().add_axes(...).
There is also nothing wrong with putting fig=plt.figure() before plotting anything.
Note that after creating a new axes, plt.gca() will return the new axes, so it is a good idea to create a reference to the main axes before adding a new one.
A convenient way to obtain a figure and an axes for later referencing is to create the figure via
fig, ax = plt.subplots()
Colormaps:
Every standard colormap has a reversed version, which has _r at the end of its name, e.g. you can use viridis_r instead of viridis.
I'm trying to learn how to animate plots using matplotlib's built in funcAnimation class. For this example, I just want to generate a 2D scatter plot of randomly distributed normal values and add a point to the plot (animate the points appearing) each time I update the points. The example code is below:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
plt.ion()
fig, ax = plt.subplots()
scat = ax.scatter([],[])
scat.axes.axis([-5, 5, -5, 5])
def update(point):
array = scat.get_offsets()
array = np.append(array, point)
scat.set_offsets(array)
return scat
def data_gen():
for _ in range(0,100):
point = np.random.normal(0, 1, 2)
yield point
ani = animation.FuncAnimation(fig, update, data_gen, interval=25, blit=False)
plt.show()
When I run this code, nothing happens. The terminal churns for a few seconds, and then nothing happens.
I'm using this as my guide: http://matplotlib.org/examples/animation/animate_decay.html, and if I use a line plot instead of a scatter plot (essentially just replacing how the points are generated in the generator of this example) it "works" as far as it generates data and updates the plots. But it is not the display I want, I want to see the point appearing on a scatter plot. To use a scatter plot, I need to not use set_data, as that is not a valid method for scatter plots; so I'm using the np.append() method which I've seen in this example:
Dynamically updating plot in matplotlib
So my question is, what am I doing wrong in this code that is causing the animation to not show up?
EDIT: I've just tried/found out that if I add:
mywriter = animation.FFMpegWriter(fps=60)
ani.save('myanimation.mp4',writer=mywriter)
It does produce an mp4 that contains the animation, I just can't get it to dynamically display as the code is running. So please focus on that problem if you are able to diagnose it. Thanks.
For future reference, #ImportanceOfBeingErnest pointed out that plot.ion() is not necessary and is specific to plotting in ipython. Removing that fixes the problem.
For some reason, I just can't get this to work. What I end up getting is two grids with axes plotted on top of each other and then the second plot plotted under this. My code works fine for a seaborn distplot:
plt.subplot(121)
h = sns.distplot(dfmain["Runs"])
plt.subplot(122)
j = sns.distplot(dfHighScores["Runs"])
But if I try and plot two factor plots side by side (they are independent so I don't want the axes to be shared), then this just doesn't work as described above:
plt.subplot(121)
h = sns.factorplot("Runs",data=dfmain)
plt.subplot(122)
j = sns.factorplot("Runs",data=dfHighScores)
I get this behavior whether I use an iPython notebook or spyder as my IDE. Any help would be greatly appreciated.
According to the documentation of factorplot it should be able do draw two plots side by side by itself. If you combine both your data frames into one (and add a column to tell between them) then something like this should work:
sns.factorplot("Runs", col="mainOrHighScores", data=dfCombined)
Otherwise I think factorplot doesn't operate on axes (unlike distplot).
In any case only functions that have an "ax" parameter for axes can draw on axes.
I have a matplotlib image plot within a wxPython panel that I zoom in on using the native matplotlib toolbar zoom.
Having zoomed in I wish to know the size of the resulting image so that I can calculate the magnification.
Moreover, I wish to know the position/dimensions of my zoomed in image in relation to the original image so that I can re-plot it again at a later time.
I don't know how to approach this. I have looked over documentation for canvas and figure but haven't found anything which would help me pin point the data I require. Thanks for any help.
You may want to read the following from the matplotlib doc:
Event handling and picking
Transformations tutorial
However, especially the transformations tutorial may take a while to wrap your head around. The transformation system is very efficient and complete, but it may take you a while to figure out what especially it is you do need.
However in your case maybe the following code snippet could be sufficient:
from matplotlib import pyplot as plt
import numpy
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(numpy.random.rand(10))
def ondraw(event):
# print 'ondraw', event
# these ax.limits can be stored and reused as-is for set_xlim/set_ylim later
print ax.get_xlim(), ax.get_ylim()
cid = fig.canvas.mpl_connect('draw_event', ondraw)
plt.show()
In the draw event you can get your axes limits, calculate a scaling and whatnot and can use it as-is later on to set the ax to the desired zoom level.
I'm confused by the relationship among matplotlib figures, axes, and subplots.
Usually, I figure out such things by looking at and experimenting with code, which typically embodies the structural relationship among entities in a object model that can be inferred from examples of what works. But in matplotlib I often find a bewildering array of ways to accomplish the same thing, which obscures the underling structure.
For example, if I want to make a simple (no subfigures) log-log figure, any of the following seem to have exactly the same effect.
import matplotlib.pyplot as plt
# All of the following seem to have the same effect:
plt.axes().loglog()
plt.gca().loglog()
plt.loglog()
plt.gcf().gca().loglog()
# These don't work though:
# plt.gcf().axes().loglog()
# plt.gcf().loglog()
I've tried the documentation and the tutorials, but I'm no wiser having done so.
What does each of the working examples above do? How to they differ? Why do the non-working examples fail? If I'm writing code that I expect others (or me) to be able to read, is one of these idioms preferred over another?
Note that my interest here is in programmatically creating images for publication or export rather than in the interactive creation of figures or in mimicking MATLABs functionality. I gather that some of the "shortcuts" above have to do with making this latter scenario work.
My standard is to get fig, ax from plt.subplots like this:
fig, ax = plt.subplots(1)
ax.loglog(a, b)
I do it this way because then you can also get multiple ax objects as a list, e.g.:
# Make a column of three figures
fig, axes = plt.subplots(3)
for ax, a, b in zip(axes, as, bs):
ax.loglog(a, b)
Or if you do a 2 by 5 grid, you get a list of lists of ax objects, so I usually unlist the list using axes.flat:
# Make a 2x5 grid of figures
nrows = 2
ncols = 5
height = nrows * 4
width = ncols * 4
# Don't ask me why figsize is (width, height) instead of (height, width)....
fig, axes = plt.subplots(nrows=2, ncols=5, figsize=(width, height))
for ax, a, b in zip(axes.flat, as, bs):
ax.loglog(a, b)
I do it this way because then I have the ax object to tweak with the appearance with afterwards. I generally don't use plt.gca() except for internal plotting functions.
plt.gcf() is getting the current figure and when you add gca() or axes() or loglog() to it, I believe they create the underlying axes. I'm not sure why the gcf()-first stuff didn't work with axes() and loglog(). So my advice is to stick to ax objects.
EDIT: removed itertools.chain stuff, swapped to axes.flat
A figure is basically a window or a file. If you make several separate figures, the idea is usually to pop up several widows or save several files.
An axis and a subplot are in some sense the same thing. For example, the figure method subplot returns an axis object. Each axis object represents a specific set of axes that you want to plot something on. Each axis can have several individual data sets plotted on it, but they will all use the same x and y axes.
Making a plot a loglog plot is determined by the function that you use to actually plot the data. For example, if you have two arrays a and b that I want to loglog plot against each other, I would use:
fig=plt.figure() #Make a figure
loglog_ax=fig.subplot(111) # Make a single axis, which is the *only* subplot
loglog_ax.loglog(a,b) # Plot the data on a log-log plot