I'm working on a project that involves exporting charts from SPSS. The value labels are supposed to be visible on the pie charts. Here's what I get, here's what I want.
The code is all working (see below how I do it). I just haven't found a way to make those "value labels" show up on the pie charts without going through the Chart Editor (double click on the chart in SPSS Viewer).
What I want is to have those labels on my pie charts like when I would click "Show Data Labels" as shown here. Is there any way to achieve this?
I'm accessing the charts in my code like this:
#in a SYNTAX file
* Encoding: UTF-8.
OMS
/DESTINATION
FORMAT=OXML
XMLWORKSPACE="my_ws"
VIEWER=YES
IMAGES=YES
IMAGEFORMAT=PNG
CHARTFORMAT=IMAGE.
BEGIN PROGRAM python.
import spss
spss.Submit("""FREQUENCIES VARIABLES=Sex
/PIECHART PERCENT
/ORDER=ANALYSIS.""")
imgs = spss.EvaluateXPath('my_ws', '/outputTree',
'//command[#command="Frequencies"]/chartTitle/chart/#imageFile' )
image=spss.GetImage( 'my_ws', imgs[-1] )
END PROGRAM.
OMSEND.
I don't think that's possible using SPSS syntax directly. The command syntax reference says about FREQUENCIES, subcommand PIECHART:
"PERCENT. [...] Percentage is displayed when you request values in the Chart Editor."
I've done that and it didn't add new code to the output document which makes me think that switching on percentages in the plot of this subcommand is not available through syntax.
You can however make a custom chart template as shown here.
Hence your code should be somthing like:
OMS
/DESTINATION
FORMAT=OXML
XMLWORKSPACE="my_ws"
VIEWER=YES
IMAGES=YES
IMAGEFORMAT=PNG
CHARTFORMAT=IMAGE.
BEGIN PROGRAM python.
import spss
spss.Submit("""set ctemplate
'<TEMPLATELOCAION>/<TEMPLATENAME>.sgt'.
FREQUENCIES VARIABLES=<VARIABLENAME>
/PIECHART PERCENT
/ORDER=ANALYSIS.
set ctemplate none.""")
imgs = spss.EvaluateXPath('my_ws', '/outputTree',
'//command[#command="Frequencies"]/chartTitle/chart/#imageFile' )
image=spss.GetImage( 'my_ws', imgs[-1] )
END PROGRAM.
OMSEND.
Related
I have written a streamlit code where I am using altair to display a chart in the front end. The made that chart to have zoom in/out functionality. I used ".interactive()" to get this done like below.
chart = alt.Chart(embd_1).mark_circle(size=30).encode(
x = 'dimention1:Q',
y = 'dimention2:Q',
tooltip=['col1'] ,
color=color).properties(width=600,height=600).add_selection(selected).interactive()
But, I am facing a problem when I do zoom in/out in my app. It's taking lot of time to get updated. once i start scrolling the mouse, it takes literally more than 10 secs to update the zoomed chart in the front end.
I was just wondering this may be because streamlit is running all the code which is beneath the altairs code as i don't know how to skip or avoid a certain code when i use zoom in/out functionality.
So, The question is how to programatically define whether the user is zooming in/out ?
like below :
if CheckZoom_SomeThingIDnotKnowYet == True:
logic to execute code1
else:
logic to execute code2
Additional Info On data and Altair Code used:
def altair_graph(embd_1):
selected = alt.selection_single(on="click", empty="none")
dom = ['Other IPs', 'Slected IP','Sel Dims']
rng_clr = ['lightgrey', 'red','blue']
color_point=alt.Color('color', scale=alt.Scale(domain=dom, range=rng_clr))
color = alt.condition(selected, alt.value('red'), color_point,legend=None)
chart = alt.Chart(embd_1).mark_circle(size=30).encode(
x = 'dimention1:Q',
y = 'dimention2:Q',
tooltip=['dimention1','dimention2'] ,
color=color
).properties(width=600,height=600).add_selection(selected).interactive()
return chart
And Sample for the above function Can be created like below:
dimention1=np.random.rand(1,100000).squeeze()
dimention2=np.random.rand(1,100000).squeeze()
colr_values = ['Other Ids', 'Slected Id','Sel Dims']
color = np.random.choice(colr_values, 100000, p=[0.9, 0.05, 0.05])
sample = pd.DataFrame({'dimention1':dimention1,'dimention2':dimention2,'color':color})
altair_graph(sample)
As shown in the example, My real time data is more than 150k data points.
Even When I have executed the above code outside streamlit, This is taking significant time to zoom in/out. Could ssomeone please provide a workaround for this problem.
Altair/VegaLite is a the moment not very performant with that many data points (I think it slows down around 20-40k somewhere). You can try alt.data_transformers.enable('data_server') for potential minor improvements and see my answer here for some more details and discussion in the comments https://stackoverflow.com/a/67349827/2166823.
I am trying to make my dash datatable interactive with my Mapbox. So when I click on “A” highlighted as the image shown below, it should show me the latitude/longitude of the point on mapbox. Correct me if I am wrong but I need to use the callback function - clickData. But I tried a few times using clickData but it did not work. Was wondering if there is any code I can refer to or any website out there that talks about dash datatable interactive with clickData . Thank you!
This is my table:
This is my coding for mapbox:
fig = px.scatter_mapbox(df4_1.to_dict('records'), lat="Latitude", lon="Longitude", hover_name="Name", hover_data=["Id"],color_discrete_sequence=["purple"], zoom=9, height=450)
fig.update_layout(mapbox_style="open-street-map")
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
clickData is not a property of a dash datatable, what you have, is an active_cell property. There are examples on how to use the active cell to update plots. The caveat is that you don't get the value inside of the selected cell, but the row, and column id. This active_cell is not reliable if you have sorting enabled, or editing.
They give an example on how to get the value if you have a static datasource(df), but If you don't have a static datasource then you need to use a sort of data sharing solution between callbacks like a dcc.Store. https://dash.plotly.com/datatable/interactivity
Anyway at this point the problem just increased in complexity so I would suggest a different simpler model:
In that case I would say to separate the mapbox and the datatable entirely and just have a text input that generates the plot and have a simple callback:
#put this before your mapbox
dcc.Input(
id="text_input_id",
type="text,
placeholder="input name of mapbox")
#app.callback(
Output("out-all-types", "children"),
Input("text_input_id", "value"),
)
def render_mapbox(val):
data=get_data(val) #do your stuff, get the data, make the plot
fig= ....
return fig
I am using Jupyter to create a report file of an analysis I'm doing. At the end of each analysis I'll provide a summary of how many errors/irregularities the analysis has found. I was wondering if there is a way to dynamically change the font color based on the results. e.g. let's say we have a variable called "font_color" and we have a if statement that sets the variable to "Red" if there are errors and "Black" if there is none, now in Jupyter markdown set the color as:
In code cell:
font_color = *IF statement to define color*
In markdown cell:
<font color={{font_color}}>
- Testing
I'm open to suggestions and if there is a better way to dynamically change font colors.
Yes, in Jupyter notebooks you can use code to output markdown as well the standout and stderr channels. And also in Jupyter notebooks you can use HTML within the markdown to color code parts of text. Combining those, you could customize something like this for your report generation:
from IPython.display import Markdown, display
a = "Good"
if a == "Good":
font_color="green"
else:
font_color="red"
def printmd(string):
display(Markdown(string))
printmd("Summary:")
printmd(f'**<font color={font_color}>Status for a.</font>**')
Also see here and here.
The tooltip example presented in the reference guide show the following examples of formatting:
hover.tooltips = [
("index", "$index"),
("(x,y)", "($x, $y)"),
("radius", "#radius"),
("fill color", "$color[hex, swatch]:fill_color"),
("foo", "#foo"),
("bar", "#bar"),
("baz", "#baz{safe}"),
("total", "#total{$0,0.00}"
The 3 examples {safe}, {$0,0.00} and "$color[hex, swatch]:fill_color" are not clear: where can i find some documentation on them?
Basically I would like to understand what is possible and what isn't.
At the moment (for instance) I have 1 input that us a very long string (its a newspaper article) that I would like to format so it only shows the x first characters.
Other example I have a field #datetime that is retrieving its value from a datetime index. At the moment the tooltip displays that value as a int64 character. How to use a format tool such as Timestamp.strftime("%d-%m-%Y") so that it shows the date time in human readable format?
But I would like to have a clearer overview of what is possible/how that aspect of bokeh works
Since this answer was originally posted, new work has gone into Bokeh to make things simpler. A datetime field can be formatted as a datetime directly by the hover tool, by specifying a formatter, e.g.:
HoverTool(tooltips=[('label', '#datetime{%F}')],
formatters={'datetime': 'datetime'})
It is no longer necessary to pre-format date fields in the data source as below (although it certainly still works). For more information see Formatting Tooltip Fields
OLD ANSWER:
This is still an open issue for the project:
https://github.com/bokeh/bokeh/issues/1239
However, given some other recent work, this should now be fairly easy to implement this feature in a natural way. I have scheduled the task for the next 0.12.6 milestone.
Also, although Bokeh has extensive and rich documentation, there are still occasional gaps. This happens to be one of them, unfortunately. I note that there is an open issue to improve this:
https://github.com/bokeh/bokeh/issues/2595
I've updated it to make sure it is also included in the 0.12.6 milestone.
In the mean time, your best option is to pre-format the data as you want it to appear in the tooltip in Python. Then add a column to your data source that has the formatted version, the configure the hover tool to display this column:
source.data['formatted_date'] = my_pretty_print(source.date['date'])
hover.tooltips = [ ("date", "#formatted_date") ]
I'm building a piece of educational software and I have pseudocode on the output where I would like to highlight a specific line of code depending on which piece of code is running.
First round()
.....
--> highlight this line and the next after it moves
Output: First round has just started
The furthest I got was doing some bash highlighting but that required me to print out the line twice. Once in black and second in a different colour. Any suggestions on how to highlight a specific line? Any help is appreciated.
EDIT: I'm using Pyqt as my GUI toolkit so my output will be displayed in a textbox
You have to get the QTextBlock object that correspond to the line (*) you want to highlight or unhighlight and use a QTextCursor to change the format of that line:
def setLineFormat(self, lineNumber, format):
cursor = QTextCursor(self.textEdit.document().findBlockByNumber(lineNumber))
cursor.setBlockFormat(format)
# with
format = QTextBlockFormat()
format.setBackground(Qt.yellow)
# or
format.clearBackground()
If you are using QSyntaxHighlighter, you could also store the state of the line in the QTextBlock with QTextBlock.setUserState() or setUserData, handle that state in the QSyntaxHighlighter.highlightBlock() method as part of the syntax highlighting, and force the previous and the current lines to be repainted with QSyntaxHighlighter.rehighlightBlock().
*: lines==blocks unless you use a custom document layout