Easiest way to plot values as symbols in scatter plot? - numpy

In an answer to an earlier question of mine regarding fixing the colorspace for scatter images of 4D data, Tom10 suggested plotting values as symbols in order to double-check my data. An excellent idea. I've run some similar demos in the past, but I can't for the life of me find the demo I remember being quite simple.
So, what's the easiest way to plot numerical values as the symbol in a scatter plot instead of 'o' for example? Tom10 suggested plt.txt(x,y,value)- and that is the implementation used in a number of examples. I however wonder if there's an easy way to evaluate "value" from my array of numbers? Can one simply say: str(valuearray) ?
Do you need a loop to evaluate the values for plotting as suggested in the matplotlib demo section for 3D text scatter plots?
Their example produces:
(source: sourceforge.net)
However, they're doing something fairly complex in evaluating the locations as well as changing text direction based on data. So, is there a cute way to plot x,y,C data (where C is a value often taken as the color in the plot data- but instead I wish to make the symbol)?
Again, I think we have a fair answer to this- I just wonder if there's an easier way?

The easiest way I've seen to do this is:
for x, y, val in zip(x_array, y_array, val_array):
plt.text(x, y, val)
Also, btw, you suggested using str(valarray), and this, as you may have noticed doesn't work. To convert an array of numbers to a sequence of strings you could use
valarray.astype(str)
to get a numpy array, or,
[str(v) for v in valarray]
to get a Python list. But even with valarray as a proper sequence of strings, plt.text won't iterate over it's inputs.

Related

Why is Pandas inverting my x-axis order? [duplicate]

This question already has answers here:
x-axis inverted unexpectedly by pandas.plot(...)
(2 answers)
Closed 4 years ago.
When I was plotting two series of data against eachother, the X axis was inverted unexpectedly. I know this question sounds pretty similar to this other: x-axis inverted unexpectedly by pandas.plot(...) and it actually is, but I want to know if this can be disabled or something, not a workaround. Let me explain myself.
I have a very simple DF that consists on a datetime index and two columns; one has humidity measurements and the other daily weights. Both of them are in descending order because when my sample loses water, it also loses weight and humidity. So my DF looks something like this, where my data is in descending order
But then, when I plot using X = "Peso" (weight), and Y = 'Humedad' (humidity), my X axis goes in ascending order insted of descending order.
My ploting code:
plt.figure(figsize=(12,9))
plt.scatter(data['Peso'],data['Humedad'])
plt.xlabel('Peso (kg)',fontsize=14)
plt.ylabel("Raw Counts",fontsize=14)
plt.xticks(rotation=90,fontsize=10)
plt.grid()
Resulting in this kind of plot, where X axis is inverted
So, I could do two simple types of workaround:
plt.scatter(sorted(data['Peso']),data['Humedad'])
or
plt.scatter(data['Peso'][::-1],data['Humedad'])
Both of them have the same result, they print my data as I wanted, BUT my xticks are still inverted:
So what I did was creating a list with my weight values in order to insert it as it follows:
semin=data['Peso']
semin=semin.tolist()
And then adding it to my plt.xticks like this
plt.xticks(semin,rotation=90,fontsize=10)
It "kind off" worked, overlaping some of the xticks as you can see in the image below:
I know I can solve this with [Locs] and general xticks information, but I really wanted to know if it's possible to just ask Pandas to follow the natural data descending order or anything similiar and avoiding all of this xticks stuff?
I've checked this too: https://github.com/pandas-dev/pandas/issues/10118
and I tried by doing the set_index suggestion:
plt.figure(figsize=(12,9))
data.set_index('Peso').Humedad.plot()
plt.xlabel('Peso (kg)',fontsize=14)
plt.ylabel("Raw Counts",fontsize=14)
plt.xticks(rotation=90,fontsize=10)
plt.grid()
And it went almost perfect, except that I needed it in scatter...
So I tried some stuff to "scatter it"
1. Putting the marker type:
data.set_index('Peso').Humedad.plot(marker='o')
Got a marker + line graph:
2. Changing .plot for .scatter to the plot:
data.set_index('Peso').Humedad.scatter()
Got this error:
AttributeError: 'Series' object has no attribute 'scatter'
3. Using both
data.set_index('Peso').Humedad.plot.scatter()
Got this one:
AttributeError: 'SeriesPlotMethods' object has no attribute 'scatter'
4. Making this giant question. Please help.
And that's all, sorry if I'm missing something or if my post is too long. I'm open to suggestions, corrections or anything you're willing to tell me.
Thanks!
Oh I just saw that the linked question actually does exactly what you need. Will leave this as here. But please refer to the linked question instead.
It's not a solution to change the ticks! The resultung plot may easily get completely wrong.
Instead google for "invert x axis" or so and find that you can invert the axis via
ax = df.plot(...)
ax.invert_xaxis()
This is not a workaround. It is the solution. (How much easier can it get?)

Selecting a single color from a matplotlib colormap in Juila

I'm constructing a graph plot in Julia and need to color each edge of the graph differently, based on some weighting factor. I can't find a way to get a specific RGB (or HSV, it doesn't matter) value from a colormap. Let's say I'd like to get the RGB value on 'jet' that would correspond to a data value of n on imshow plot.
In python, I would just use jet(n), where n is the value along the colormap in which I am interested. PyPlot in Julia doesn't seem to have wrapped this functionality. I've also already tried indexing into the cmap object returned from get_cmap(). Any advice?
I'm stumped, so even an approximate solution would help. Thanks!
Maybe you can look at the Colors.jl package (https://github.com/JuliaGraphics/Colors.jl):
using Colors
palette = colormap("Oranges", 100)
Then you can access each color with palette[n]. Or are you using PyCall? A code describing what you're trying to do would help.

How can I plot this kind of picture using Matplotlib or Mayavi?

I have three 2d arrays: X,Y,Z, which contain irregular 3d points coordinate,respectively.And another 2d array data, which contains the values on those points.
What I want to do is to display this data in 3d space , with 0 value part masked out.Much like this one:
In matlab, I can use function fill3 to achieve this, but how can I plot the same kind of picture in matplotlib or mayavi ? I have tried to use mask array ,plot_surface and colorface together, as the example here:
Plotting a masked surface plot using python, numpy and matplotlib
and it worked, the result is the link below:
but that is really really slow, and will cost too much time. Is there a better way?
Well, today I find out an alternative way to solve the problem. Except using plot_surface, I choose to use scatter3D,
the core code is some what like this
aa=np.shape(X)[0]
bb=np.shape(X)[1]
x=X.reshape(aa*bb)
y=Y.reshape(aa*bb)
z=Z.reshape(aa*bb)
data=data.reshape(aa*bb)
x1=[]
y1=[]
z1=[]
da1=[]
for i in range(aa*bb):
if data[i]>0:
x1.append(x[i])
y1.append(y[i])
z1.append(z[i])
da1.append(data[i])
my_cmap=cm.jet
my_cmap.set_over('c')
my_cmap.set_under('m')
N=da1/max(da1)
fig=plt.figure()
ax=fig.add_subplot(111,projection='3d')
ax.scatter3D(x1,y1,z1,s=6,alpha=0.8,marker=',',facecolors=my_cmap(N),lw=0)
and the result is like this:
this doesn't really solve the problem, but it is a nice substitution.
I'll keep waiting for more answers.

Colorbar for imshow, centered on 0 and with symlog scale

I want to generate a grid of plots, of several arrays, with positive and negative values, with log scale, sharing the same colorbar.
I've achieved the sharing part of the colorbar (using ImageGrid and common max and min values), and I know that I could get a logarithmic scale using LogNorm() on the imshow call in the case of only positive values. But given the presence of negative values, I would need a colorbar on symmetric logarithmic scale.
I have found what would be the solution on https://stackoverflow.com/a/7741317/1101750 , but running the sample code Yann provides gives me very different results, cleary wrong:
Reviewing the code, I'm not able to grasp what's going on.
In addition to that, I've discovered that on Matplotlib 1.2, scale.SymmetricalLogScale.SymmetricalLogTransform asks for a new argument not explained on the documentation (linscale, which looking at the code of other transforms I assume that leaving it as 1 is a safe value).
Is the easiest solution subclassing LogNorm?
I've used a pretty simple recipe in the past to do exactly this, without the need to do any subclassing. matplotlib.colors.SymLogNorm provides most of the functionality you need, except that I've found it necessary to generate the tick marks by hand. Note that this solution uses matplotlib 1.3.0, and I may be using features that weren't available with 1.2.
def imshow_symlog(my_matrix, vmin, vmax, logthresh=5):
img=imshow( my_matrix ,
vmin=float(vmin), vmax=float(vmax),
norm=matplotlib.colors.SymLogNorm(10**-logthresh) )
maxlog=int(np.ceil( np.log10(vmax) ))
minlog=int(np.ceil( np.log10(-vmin) ))
#generate logarithmic ticks
tick_locations=([-(10**x) for x in xrange(minlog,-logthresh-1,-1)]
+[0.0]
+[(10**x) for x in xrange(-logthresh,maxlog+1)] )
cb=colorbar(ticks=tick_locations)
return img,cb
Since 1.3 matplotlib has a SymLogNorm. http://matplotlib.org/api/colors_api.html#matplotlib.colors.SymLogNorm

Octave colorbar and units

In GNU Octave you can make a picture where different colors represent different values in a matrix. You can also add a colorbar, which shows what color corresponds to what value.
Is it possible to somehow add units to the values shown in the colorbar? Instead of saying “0.36” it would say “0.36 V/nm”? I know this is possible in Matlab, but I can’t figure out how to do it in Octave. Any good workarounds?
I assume someone here will mention that I should use matplotlib instead (that usually happens). How would you accomplish the same thing with that?
The matplotlib answer (using pylab) is
imshow(random((20,20)))
colorbar(format='%.2f V/nm')
In Octave it seems that the following works (but I'm no Octave expert so maybe there's a better way):
c=colorbar();
labels = {};
for v=get(c,'ytick'), labels{end+1} = sprintf('%.2f V/nm',v); end
set(c,'yticklabel',labels);