I have code that plot tabular data I have . The code choose everytime different row (observation) to plot and display the data and the legend with the name of the observations.
My problem is that that even if I change the displayed data using the iloc (e.g changing the rows to be displayed) , I still get the same legend .
for example:
If I use this code, that suppose to display rows 0-10:
SavitzkyGolay(db_plants.iloc[:10,5:],25,2).T.plot(title='25/06/2019 17:00',figsize=(17,10))
plt.legend(db_plants['plant'])
The result I get is this :
But when I change the iloc:
SavitzkyGolay(db_plants.iloc[12:22,5:],25,2).T.plot(title='25/06/2019 17:00',figsize=(17,10))
plt.legend(db_plants['plant'])
I get the same legend:
*I can't share the original dataframe
*The observations names are different for sure
My end goal: to have the correct observations displayed in the legend
EDIT: I have used the iloc :
SavitzkyGolay(db_plants.iloc[12:22,5:],25,2).T.plot(title='25/06/201917:00',figsize=(17,10))
plt.legend(db_plants['plant'].iloc[12:22,5:])
But I still gett error:
IndexingError: Too many indexers
Related
first I'm going to explain what my script does, and then problem. I'm trying to automatize a task every 5 mins. This task involves pandas Tkinter and Matplotlib. I'll attach some guide code of mine to help understand this. First, I do some big task to initialize software programs (petroleum ones) to open files and then work with them. Second, I create a Treeview window and a plot window from Tkinter, then I need them to be updated every 5 mins, the Treeview is updated as expected, but the main problem is that I can't update or append some data to an empty dataframe;which is generated in every loop, need this new data to update plot every5 mins. I tried with append like in code, but it's not working, thanks in advance people.
import pandas
import tkinter as tk
## big task here
#create an empty dataframe
dfoil = pd.DataFrame(columns=[['Date','Oil Rate Cal','Oil Rate Mesu']])
root=tk.Tk
def update_item(df,df0,df01,df02):
#where df,df0,df01,df02 are dataframes are updated and are working correctly
#another big task here where i can get the desire results and i can see a treeview updating every 5 mins
#.........
#.........
#time2 comes from a working dataframe
dfoil.append({'Date':time2, 'Oil Rate Cal':dff1.iat[3,11],'Oil Rate Mesu':dff1.iat[3,12]},ignore_index=True)
root.after(1000*60*5, update_item, df,df0,df01,df02)
update_item(my_df,raiserdf,separetordf,compressorsdf)
root.mainloop
dfoil is the dataframe that is always getting empty after everyloop
You need to add inside the function:
global dfoil
This will make the dataframe global and 'exist' outside the function
Another option is at the end of the function:
return dfoil
and change the line that calls the function to:
dfoil = update_item(my_df,raiserdf,separetordf,compressorsdf)
Also the append does not occur 'inplace' so you need:
dfoil = dfoil.append({'Date':time2, 'Oil Rate Cal':dff1.iat[3,11],'Oil Rate Mesu':dff1.iat[3,12]},ignore_index=True)
I'm generating pie charts using XLSX writer, and everything is going perfectly except for one thing: I can't seem to find a way to control the text from wrapping in my data labels (which contain percentage values). Any font size above a 10 causes the '%' symbol to wrap below the digits (you can see this in the image I've attached below). I'm trying to generate many charts, so adjusting them manually could be costly time-wise.
The docs suggest that wrapping can be enabled or disabled from num_format. For cells, this property is set with a 'format' object. However, while data label text has a num_format property, the docs explicitly state that it must be set with a string literal and cannot take a format object. I have no clue how to prevent string wrapping with a string literal format.
Alternatively, I've looked into expanding/reducing the width/height of the data labels. However, this option also seems to be missing from the library.
From what I can tell, none of the other properties seem to suggest a way to avoid wrapping text.
My question is, is there a solution I'm missing? I'll leave some of my output and code below.
Current Code:
chart.add_series({
'categories' : '={}!B1:C1'.format(product_sheetname),
'values' : '={}!B2:C2'.format(product_sheetname),
'data_labels':{
'percentage':True,
'fill': {'color':'#363636'},
'font': {'name':'Arial (Body)', 'color':'white', 'size':16},
},
'points' : [
{'fill':{'color':'#4471d2'}},
{'fill':{'color':'#ff871c'}}
]
})
Current Output:
UPDATE:
A quick fix per the comment below is to scale up the size of the chart in general. While this solves the wrapping issue, it defeats the purpose of using a larger font.
There isn't any way in XlsxWriter to adjust the size of the data label but Excel should do it automatically to get the best result.
I tried to replicate but didn't see the text wrap that you are getting (even though I tried 3 different versions of Excel):
import xlsxwriter
workbook = xlsxwriter.Workbook('chart_pie.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_row('B1', ['Apple', 'Cherry'])
worksheet.write_row('B2', [53, 47])
chart = workbook.add_chart({'type': 'pie'})
product_sheetname = 'Sheet1'
chart.add_series({
'categories' : '={}!B1:C1'.format(product_sheetname),
'values' : '={}!B2:C2'.format(product_sheetname),
'data_labels':{
'percentage':True,
'fill': {'color':'#363636'},
'font': {'name':'Arial (Body)', 'color':'white', 'size':16},
},
'points' : [
{'fill':{'color':'#4471d2'}},
{'fill':{'color':'#ff871c'}}
]
})
worksheet.insert_chart('B3', chart, {'x_offset': 25, 'y_offset': 10})
workbook.close()
Output:
I am trying to write a pine script with two indicators one overlaid on the chart (EMA) and another on its own?(Stoch) I cannot seem to find any info on how to separate these (Visually) but keep them within 1 pine script, ie to be able to take trading decisions based on these.
The earlier answer from Luc is right, unfortunately. Each script can either create plots that are overlaid on the default price chart, or shown in a different pane, but not both. But there is a workaround.
Suppose you've made some non-trivial calculation in your script and you'd like to put it in different pane. E.g. the next code:
//#version=4
study(title="Stochastic", shorttitle="Stoch", format=format.price, precision=2)
periodK = input(14, title="K", minval=1)
periodD = input(3, title="D", minval=1)
smoothK = input(3, title="Smooth", minval=1)
k = sma(stoch(close, high, low, periodK), smoothK)
d = sma(k, periodD)
plot(k, title="%K", color=color.blue)
plot(d, title="%D", color=color.orange)
h0 = hline(80)
h1 = hline(20)
fill(h0, h1, color=color.purple, transp=75)
// This next plot would work best in a separate pane
someNonTrivialCalculatedSeries = close
plot(ema(someNonTrivialCalculatedSeries, 25), title="Exporting Plot")
Because they have different scale, one of them most likely will break another indicator's scale.
So you'd like show Stoch in different pine, whereas ema() should be overlayed with the main chart. For that you should make the next steps:
Turn off in the study's the extra plot to return scale to normal:
Apply to the chart the next script:
//#version=4
study("NonOverlayIndicator", overlay=true)
src = input(defval=close, type=input.source)
plot(src)
Choose in the second's script inputs source required plot from the first script:
And voilĂ - you got the plots in different pines:
But if you want split the plots because you have retrictions on amount of studies you allowed to apply (e.g. 3 for free-account) - that won't help you.
It cannot be done. A script runs either in overlay=true mode on the chart, in which case it cannot direct plots elsewhere, or in a separate pane when overlay=false (the default).
When the script is running in a pane, it can change the color of the chart bars using barcolor(), but that's the only way it can modify the chart.
It is possible to rescale signals so that multiple bounded (e.g., 0-100, -1 to +1) signals generated by one script appear one on top of the other, but this is typically impossible in overlay mode, as the vertical scale varies with the bars on the chart. The only way for an overlay script to work with its own scale is when it uses No scale, but this prevents the indicator's plots to plot relative to price, and so the chart's bars.
Nice workaround from Michael.
Unfortunately, this only seems to work to pass data for one plot.
I would like to pass data for 3 different plots to the stock price graph.
If I try this, for 'input.source' I can only select the standard sources: "open, high, low, close ...". I can not select the data from other indicators.
If I remove plots 2 and 3, it works as Michael described.
Anybody has a workaround for the workaround..? ;-)
When using the searchbar to search for a product, I also get results that do not contain the string I input.
For example, inputting "70" shows the following results : HeatMaster 120, HeatMaster 70, HeatMaster 85.
This is because the rows containing this data have another column, numerical, which also contains "70" (e.g: 170); is there a way I can force this plugin to consider only one specified column when searching ? Or a plugin for this ?
Doing a little test-driven research, I found out that the default behavior of the search box is to search all the fields and return all the rows that contain the input string; to search on only a specific column, I used the columnFilter add-on for jQuery dataTables.
http://jquery-datatables-column-filter.googlecode.com/svn/trunk/default.html
http://imageshack.us/photo/my-images/339/41988730.jpg/
I'm trying to figure out how to tweak the options for the legend in this graph (see link above). Specifically I'd like the new = part of the label to disappear. Next to each line I'd like just the name of the company. I'm using the xtline command to generate the graph. Each line on the graph should represent a distinct value of the variable "company" (there should be 11 distinct values).
xtline revenue, overlay t(week_name) i(company)
Thanks!
Use the label() sub-option of the legend() option. Here's the example on p. 474 of the Stata 12 manual:
line le_m le_f year, legend(label(1 "Males") label(2 "Females"))
You can also use the order() sub-option to order the legend entries according to the order of the curves on the graph. Type "help graph legend" for more information and links to the Manual.
However I don't find legends with so many entries to be helpful. You'd have a more readable plot if you specify "legend(off)"; "yscale(log)"; and add the appropriate label next to each curve with the Graph Editor.