multiple y axes (matplotlib) - unable to define scale increments - python

Two follow-up questions to a post from yesterday (Multiple Y Axes), is it possible to:
Set the scale increments with ylim or yticks? (so that they line up at 5 steps each)
Change the right Y-axis data to kind='bar' ?
The gridlines do not match up (see image):
Edit: I did not understand that I was plotting in 2D lines by default, so I was trying to change the "kind" as I would in pandas; for example, df.plot(kind='').

Related

Make two plots in a single row using imshow in python

I want to make plots of the same data for two regions, so they should be placed side by side in a single row for compactness.
Below is my code. As we can expect, it's creating the plots one after another in a column, since the two plots are not linked to each other.
I tried looking for side by side plot methods, however they don't seem to work with imshow() and I need to use imshow() in my code. I've attached my output below as well.
Any suggestions?
wvcount3D=fanibl['IMG_WV'][:]
wvcount3D.shape
wvcount=np.squeeze(wvcount3D)
wvcount.shape
image_wv_global=plt.imshow(wvcount,vmin=800,vmax=975)
plt.title("Global 2D plot for Water Vapor Count for Fani before landfall")
plt.colorbar(image_wv_global)
plt.grid()
plt.show()
image_wv_asia=plt.imshow(wvcount,vmin=800,vmax=975)
plt.title("Asia-specific plot for Water Vapor Count for Fani before landfall")
plt.axis([300, 1000, 200, 700])
plt.colorbar(image_wv_asia)
plt.grid()
plt.show()
This is my current output, plots in a single column:

Matplotlib plotting data that doesnt exist

I am trying to plot three lines on one figure. I have data for three years for three sites and i am simply trying to plot them with the same x axis and same y axis. The first two lines span all three years of data, while the third dataset is usually more sparse. Using the object-oriented axes matplotlib format, when i try to plot my third set of data, I get points at the end of the graph that are out of the range of my third set of data. my third dataset is structured as tuples of dates and values such as:
data=
[('2019-07-15', 30.6),
('2019-07-16', 20.88),
('2019-07-17', 16.94),
('2019-07-18', 11.99),
('2019-07-19', 13.76),
('2019-07-20', 16.97),
('2019-07-21', 19.9),
('2019-07-22', 25.56),
('2019-07-23', 18.59),
...
('2020-08-11', 8.33),
('2020-08-12', 10.06),
('2020-08-13', 12.21),
('2020-08-15', 6.94),
('2020-08-16', 5.51),
('2020-08-17', 6.98),
('2020-08-18', 6.17)]
where the data ends in August 2020, yet the graph includes points at the end of 2020. This is happening with all my sites, as the first two datasets stay constant knowndf['DATE'] and knowndf['Value'] below.
Here is the problematic graph.
And here is what I have for the plotting:
fig, ax=plt.subplots(1,1,figsize=(15,12))
fig.tight_layout(pad=6)
ax.plot(knowndf['DATE'], knowndf['Value1'],'b',alpha=0.7)
ax.plot(knowndf['DATE'], knowndf['Value2'],color='red',alpha=0.7)
ax.plot(*zip(*data), 'g*', markersize=8) #when i plot this set of data i get nonexistent points
ax.tick_params(axis='x', rotation=45) #rotating for aesthetic
ax.set_xticks(ax.get_xticks()[::30]) #only want every 30th tick instead of every daily tick
I've tried ax.twinx() and that gives me two y axis that doesn't help me since i want to use the same x-axis and y-axis for all three sites. I've tried not using the axes approach, but there are things that come with axes that i need to plot with. Please please help!

Do not display missing values ​matplotlib

I would like to remove the flat lines on my graph by keeping the labels x.
I have this code which gives me a picture
dates = df_stock.loc[start_date:end_date].index.values
x_values = np.array([datetime.datetime.strptime(d, "%Y-%m-%d %H:%M:%S") for d in dates])
fig, ax = plt.subplots(figsize=(15,9))
# y values
y_values = np.array(df_stock.loc[start_date:end_date, 'Bid'])
# plotting
_ = ax.plot(x_values, y_values, label='Bid')
# formatting
formatter = mdates.DateFormatter('%m-%d %H:%M')
ax.xaxis.set_major_formatter(formatter)
The flat lines correspond to data which does not exist I would like to know if it is possible not to display them while keeping the gap of the x labels.
thank you so much
You want to have time on the x-axis and time is equidistant -- independent whether you have data or not.
You now have several options:
don't use time on the x-axis but samples/index
do as in 1. but change the ticks & labels to draw time again (but this time not equidistantly)
make the value-vector equidistant and use NaNs to fill the gaps
Why is this so?
Per default, matplotlib produces a line plot, which connects the points with lines using the order in which they are presented. In contrast to this a scatter plot just plots the individual points, not suggesting any underlying order. You achieve the same result as if you would use a line plot without markers.
In general, you have 3-4 options
use the plot command but only plot markers (add linestyle='')
use the scatter command.
if you use NaNs, plotdoes not know what to plot and plots nothing (but also won't connect non-existing points with lines)
use a loop and plot connected sections as separate lines in the same axes
options 1/2 are the easiest if you want to do almost no changes on your code. Option 3 is the most proper and 4 mimics this result.

Python, Seaborn: Logarithmic Swarmplot has unexpected gaps in the swarm

Let's look at a swarmplot, made with Python 3.5 and Seaborn on some data (which is stored in a pandas dataframe df with column lables stored in another class. This does not matter for now, just look at the plot):
ax = sns.swarmplot(x=self.dte.label_temperature, y=self.dte.label_current, hue=self.dte.label_voltage, data = df)
Now the data is more readable if plotted in log scale on the y-axis because it goes over some decades.
So let's change the scaling to logarithmic:
ax.set_yscale("log")
ax.set_ylim(bottom = 5*10**-10)
Well I have a problem with the gaps in the swarms. I guess they are there because they have been there when the plot is created with a linear axis in mind and the dots should not overlap there. But now they look kind of strange and there is enough space to from 4 equal looking swarms.
My question is: How can I force seaborn to recalculate the position of the dots to create better looking swarms?
mwaskom hinted to me in the comments how to solve this.
It is even stated in the swamplot doku:
Note that arranging the points properly requires an accurate transformation between data and point coordinates. This means that non-default axis limits should be set before drawing the swarm plot.
Setting an existing axis to log-scale and use this for the plot:
fig = plt.figure() # create figure
rect = 0,0,1,1 # create an rectangle for the new axis
log_ax = fig.add_axes(rect) # create a new axis (or use an existing one)
log_ax.set_yscale("log") # log first
sns.swarmplot(x=self.dte.label_temperature, y=self.dte.label_current, hue=self.dte.label_voltage, data = df, ax = log_ax)
This yields in the correct and desired plotting behaviour:

Seaborn Pairgrid: How to share all axes for all off-diagonal plots (i.e each plot shares axes with its mirror)?

I am trying to plot a 3x3 sns.PairGrid of plots. Currently, the axes are shared for the bottom triangle, and the upper triangle separately. Put another way, the x axes and y axes are only shared with their respective columns/row. So the x-axis of plot (1,0) is shared with (0,0) and (2,0).
However, I would like all the off-diagonal plots to share their axes. So for example, I want (1,0) share its x-axis with (0,0) and (2,0) like before, but also with (0,1).
Also, I would prefer it if the y-axes aren't shared with the plots on the diagonal, as those are 1-D kernel density plots, and so if I share their y-axes, some of them will be invisible as the size of the probability density functions isn't the same.
Here's my current code if it helps:
The 3 parameters I am plotting against each other are called 'A', 'C', and 'logsw', and are contained in the pandas.DataFrame called hyperparams
g = sns.PairGrid(hyperparams, diag_sharey=False)
g.map_lower(sns.kdeplot)
g.map_upper(plt.scatter, marker='+')
g.map_diag(sns.kdeplot)
And here's a trivial example of the output plot:
The images on the bottom left are scaled differently to the images on the upper right, which is what I'm trying to avoid.
High level, you could manually set the x and y limits and tickmarks. You could also set variables to what you want to share and then just reuse the variable in the 3 like subplots.
That way, if you need to make an adjustment, you just update the variable and the 3 plots that share it now update all at once.
In the past, I created code for a Pair grid where I set the limits and ticks on all subplots along the y-axis, and all plots along the x-axis in this manner.
There is currently no way of automatically doing this in Seaborn. The workaround suggested in the comment that seems to have solve the problem is to set the axes limits manually for the diagonal subplots. Using variables for the x and y limits ensures that they only need to be changed in one place when updating the axes ranges.

Categories

Resources