Problem in matplotlib plotting axes with twinx - python

I'm new to matplotlib. I'm writing a Stock Market application in Python.
In the application I have a chart with 2 different line-graphs to display. One is "Price" and the other is "VVAP Indicator". I'm trying to plot it using matplotlib twinx() function, so that both of them share the same x-axis.
The problem is: the price dataset has a length of 100, while the "VVAP Indicator" dataset has a length of just 1 (it will increase to 100 as new data is fetched from the server and calculated).
Here is my code:
self.figure, ax1 = plt.subplots()
ax1.plot(prices_dataframe, 'b-')
ax2 = ax1.twinx()
ax2.plot(vwaps_dataframe, 'r-')
plt.autoscale(enable=True, axis='x')
plt.title("Intraday with VWAP")
plt.grid()
helper.chart_figure = self.figure
Here are the datasets:
And here is what I get on the charts:
How do I solve this? Do I need to pad up the second dataset with dummy rows? Or is there a more easy and elegant solution to my problem? Any help would be appreciated.
Thanks in advance.

I found the solution to the issue in the dataset image:
The first dataset was having timezone-aware datetime objects, while in the second dataset I was inserting date and time as a string.
I also had to add the following lines to make the x axis display the proper time in my timezone:
ax1.xaxis_date(tz='Asia/Kolkata')
ax2.xaxis_date(tz='Asia/Kolkata')

Related

Plot time series of paired columns

I have an excle file and would like to create time series plots. For a quick view of data for one site, caputred image is give below. I would like to plot two categories of data - one is modelled and the other is monitoring data. For example, "pH" and "pH data" on one plot, "WQ[SO4,Dissolved]" and "WQ data[SO4,Dissolved]" on one plot, as such for all the remaining 30 paires. That means 60 columns of data to plot.
enter image description here
My approach was:
1) read excel data as DF;
2) creat a list for each category of parameters to plot
3) use the "zip" function to creat a paralle list: parameters_pair = zip(parameters_model,parameters_monitor)
4) plot, some codes shown below.
for i,j in parameters_pair:
fig = plt.figure(figsize=(10, 7)
ax.plot(df_Plot['Tstamps'], df_Plot[i],
label=site, color='blue', linestyle='solid') #fillStyle='none'
ax.plot(df_Plot['Tstamps'], df_Plot[j],
label=site, color='orange', marker='s', markersize='4', linestyle='')
My code can plot for i or j individually but if it does not put modelled and monitoring data on one plot and iterate paralelly as expected. Could you please suggest what functions to use to solve this issue? Thank you very much.

Problems with plt.subplots, which should be the best option?

I'm new in both python and stackoverflow... I come from the ggplot2 R background and I am still getting stacked with python. I don't understand why I have a null plot before my figure using matplotlib... I just have a basic pandas series and I want to plot some of the rows in a subplot, and some on the others (however my display is terrible and I don't know why/how to fix it). Thank you in advance!
df = organism_df.T
fig, (ax1,ax2) = plt.subplots(nrows=1,ncols=2,figsize=(5,5))
ax1 = df.iloc[[0,2,3,-1]].plot(kind='bar')
ax1.get_legend().remove()
ax1.set_title('Number of phages/bacteria interacting vs actual DB')
ax2 = df.iloc[[1,4,5,6,7]].plot(kind='bar')
ax2.get_legend().remove()
ax2.set_title('Number of different taxonomies with interactions')
plt.tight_layout()
The method plot from pandas would need the axes given as an argument, e.g., df.plot(ax=ax1, kind='bar'). In your example, first the figure (consisting of ax1 and ax2) is created, then another figure is created by the plot function (at the same time overwriting the original ax1 object) etc.

How can I return a matplotlib figure from a function?

I need to plot changing molecule numbers against time. But I'm also trying to investigate the effects of parallel processing so I'm trying to avoid writing to global variables. At the moment I have the following two numpy arrays tao_all, contains all the time points to be plotted on the x-axis and popul_num_all which contains the changing molecule numbers to be plotted on the y-axis.
The current code I've got for plotting is as follows:
for i, label in enumerate(['Enzyme', 'Substrate', 'Enzyme-Substrate complex', 'Product']):
figure1 = plt.plot(tao_all, popul_num_all[:, i], label=label)
plt.legend()
plt.tight_layout()
plt.show()
I need to encapsulate this in a function that takes the above arrays as the input and returns the graph. I've read a couple of other posts on here that say I should write my results to an axis and return the axis? But I can't quite get my head around applying that to my problem?
Cheers
def plot_func(x, y):
fig,ax = plt.subplots()
ax.plot(x, y)
return fig
Usage:
fig = plot_func([1,2], [3,4])
Alternatively you may want to return ax. For details about Figure and Axes see the docs. You can get the axes array from the figure by fig.axes and the figure from the axes by ax.get_figure().
In addition to above answer, I can suggest you to use matplotlib animation.FuncAnimation method if you are working with the time series and want to make your visualization better.
You can find the details here https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html

How to make Candlesticks wider?

I am relatively new to coding, so I apologize beforehand for this simple question:
I want to plot 2week candlesticks.
After I resampled my dataset in 2 week chunks I plotted the results. Unfortunately, matplotlib plots the chart with the complete date range, meaning that there are 14 day gaps between each candle. I already have tried to use ax.xaxis.set_major_locator(WeekdayLocator(byweekday=MO, interval=2)) but this just formats the labels of the x-axis, not the used values.
The Code:
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)
ax.xaxis.set_major_formatter(weekFormatter)
candlestick_ohlc(ax, zip(mdates.date2num(quotes.index.to_pydatetime()),
quotes['open'], quotes['high'],
quotes['low'], quotes['close']),
width=0.6)
plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
plt.show()
Heres the result:
So how can I create a continuous graph where the candlesticks are closer to each other ?
[EDIT]
Wow, the simple solution is to put the width higher... I am really sorry for this. It was my first post here :D
I think the problem is with minor locator, which makes smaller marks on x axis every day. You can use ax.xaxis.minorticks_off() to disable them.
[EDIT]
Hmm, now that I reread the question I think that you want candlesticks to be wider. There is width parameter to do just so.

How to plot non-numeric data in Matplotlib

I wish to plot the time variation of my y-axis variable using Matplotlib. This is no problem for continuously discrete data, however how should this be tackled for non-continuous data.
I.e. if I wanted to visualise the times at which my car was stationary on the way to work the x-axis would be time and the y-axis would be comprised of the variables 'stationary' and 'moving' (pretty useless example i know)
The non-continuous data would need to be indexed somehow, but i don't know how to proceed...any ideas?
Is this the type of thing you want? (If not, you might want to check out the matplotlib gallery page to give yourself some ideas, or maybe just draw a picture and post it.)
import matplotlib.pyplot as plt
data = [0]*5 + [1]*10 + [0]*3 +[1]*2
print data
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(data)
ax.set_yticks((0, 1.))
ax.set_yticklabels(('stopped', 'moving'))
ax.set_ybound((-.2, 1.2))
ax.set_xlabel("time (minutes)")
plt.show()

Categories