Why is altair single select not changing my graph? - dropdown

I've tried to google why this isn't working but it doesn't appear obvious to me. Can you please tell me why the selection dropdown isn't changing the graph?
Thanks
source = data.unemployment_across_industries.url
df = data.unemployment_across_industries()
series_val = df.series.str.split(',').explode().unique().tolist()
print(series_val)
input_dropdown = alt.binding_select(options=series_val, name='Industry: ')
selection = alt.selection_single(fields=['series'], bind=input_dropdown)
fig3 = alt.Chart(source).mark_area().encode(
alt.X('yearmonth(date):T',
axis=alt.Axis(format='%Y', domain=False, tickSize=0)
),
alt.Y('sum(count):Q', stack='center', axis=None),
alt.Color('series:N',
scale=alt.Scale(scheme='category20b')
)
).add_selection(
selection
)
fig3

The selection doesn't change the graph because you have not conditioned any part of the graph on the selection (none of your encodings depend on the value of the selection, nor is the data filtered based on the selection).
Perhaps you intended to do something like this?
fig3 = alt.Chart(source).mark_area().encode(
alt.X('yearmonth(date):T',
axis=alt.Axis(format='%Y', domain=False, tickSize=0)
),
alt.Y('sum(count):Q', stack='center', axis=None),
color=alt.condition(selection,
alt.Color('series:N', scale=alt.Scale(scheme='category20b')),
alt.value('lightgray'))
).add_selection(
selection
)
For more on how to use selections in Altair charts, see https://altair-viz.github.io/user_guide/interactions.html

Related

R tableGrob cell colors with condition on multiple columns

Is there a way to put colors on all the cells of a tableGrob that are not 0 ?
I have this table with a lot of lines
[][1]
[1]: https://i.stack.imgur.com/w7RCJ.png
I am using tableGrob and then grid.arrange to put 2 tables on the same page with some text
tab1<-tableGrob(tab_glob,rows=NULL,theme = ttheme_default(10),widths=unit(rep(1/ncol(tab_glob), ncol(tab_glob)), "null"), heights=unit(rep(0.95/nrow(tab_glob), nrow(tab_glob)),"npc"))
tab2<-tableGrob(Notes_tous,rows=NULL,theme = ttheme_default(11))
footnote<- textGrob("Moyenne référence = résultats techniciens référents")
padding<-unit(0.5,"line")
tab3<-gtable_add_rows(tab2,
heights = grobHeight(footnote)+ padding,pos=0)
tab3 <- gtable_add_grob(tab3,list(footnote),
t=1, l=1,
r=ncol(tab2))
pdf(paste("Table_",i,".pdf",sep = ""),width=10,height=15) #save in pdf
Point_tab<-grid.arrange(tab1,tab3,ncol=1,nrow=2, top=textGrob("\n \n \nNombre de pointages par note",gp=gpar(fontsize=14,font=3)))
dev.off()
In the first table, showing all the values, I am looking for a way to highlight the values that are not 0 in all the columns. All the answers I have found on the internet are for particular cells or a particular value... Do you have any idea to help me update my code ?
Kind regards,

geom_nodelabel_repel() position for circular ggraph plot

I have a network diagram that looks like this:
I made it using ggraph and added the labels using geom_nodelabel_repel() from ggnetwork:
( ggraph_plot <- ggraph(layout) +
geom_edge_fan(aes(color = as.factor(responses), edge_width = as.factor(responses))) +
geom_node_point(aes(color = as.factor(group)), size = 10) +
geom_nodelabel_repel(aes(label = name, x=x, y=y), segment.size = 1, segment.color = "black", size = 5) +
scale_color_manual("Group", values = c("#2b83ba", "#d7191c", "#fdae61")) +
scale_edge_color_manual("Frequency of Communication", values = c("Once a week or more" = "#444444","Monthly" = "#777777",
"Once every 3 months" = "#888888", "Once a year" = "#999999"),
limits = c("Once a week or more", "Monthly", "Once every 3 months", "Once a year")) +
scale_edge_width_manual("Frequency of Communication", values = c("Once a week or more" = 3,"Monthly" = 2,
"Once every 3 months" = 1, "Once a year" = 0.25),
limits = c("Once a week or more", "Monthly", "Once every 3 months", "Once a year")) +
theme_void() +
theme(legend.text = element_text(size=16, face="bold"),
legend.title = element_text(size=16, face="bold")) )
I want to have the labels on the left side of the plot be off to the left, and the labels on the right side of the plot to be off to the right. I want to do this because the actual labels are quite long (organization names) and they get in the way of the lines in the actual plot.
How can I do this using geom_nodelabel_repel()? i've tried different combinations of box_padding and point_padding, as well as h_just and v_just but these apply to all labels and it doesn't seem like there is a way to subset or position specific points.
Apologies for not providing a reproducible example but I wasn't sure how to do this without compromising the identities of respondents from my survey.
Well, there is always the manually-intensive, yet effective method of separately adding the geom_node_label_repel function for the nodes on the "left" vs. the "right" of the plot. It's not at all elegant and probably bad coding practice, but I've done similar things myself when I can't figure out an elegant solution. It works really well when you don't have a very large dataset to begin with and if you are not planning to make the same plot over and over again. Basically, it would entail:
Identifying if there exists a property in your dataset that places points on the "left" vs. the "right". In this case, it doesn't look like it, so you would just have to create a list manually of those entries on the "left" vs. "right" of your plot.
Using separate calls to geom_node_label_repel with different nudge_x values. Use any reasonable method to subset the "left" and "right datapoints. You can create a new column in the dataset, or use formatting in-line like data = subset(your.data.frame, property %in% left.list)
For example, if you created a column called subset.side, being either "left" or "right" in your data.frame (here: your.data.frame), your calls to geom_node_label_repel might look something like:
geom_node_label_repel(
data=subset(your.data.frame, subset.side=='left'),
aes(label=name, x=x, y=y), segment.size=1, segment.color='black', size=5,
nudge_x=-10
) +
geom_node_label_repel(
data=subset(your.data.frame, subset.side=='right'),
aes(label=name, x=x, y=y), segment.size=1, segment.color='black', size=5,
nudge_x=10
) +
Alternatively, you can create a list based on the label name itself--let's say you called those lists names.left and names.right, where you can subset accordingly by swapping in as represented in the pseudo code below:
geom_node_label_repel(
data=subset(your.data.frame, name %in% names.left),...
nudge_x = -10, ...
) +
geom_node_label_repel(
data=subset(your.data.frame, name %in% names.right),...
nudge_x = 10, ...
)
To be fair, I have not worked with the node geoms before, so I am assuming here that the positioning of the labels will not affect the mapping (as it would not with other geoms).

SSRS Change background colour of cell in a expanding matrix

I have a matrix table that looks like this:
="£" & FormatNumber(Sum(Fields!CalculatedFee.Value *
Fields!Unit.Value), 2, False, False, True)
When the report is run, it looks like this:
As you can see, it populates this year's and the previous year's data, the year is a group also.
What I would like to achieve is to colour the cell of this year's net when it is lower than the previous.
For example:
I have tried many many ways to make this work but I'm stuck. My latest incarnation is this, which fails:
=IIF(Fields!Year.Value = Year(now) and Sum(Fields!CalculatedFee.Value *
Fields!Unit.Value) < IIF(Fields!Year.Value = Year(now)-1 and
Sum(Fields!CalculatedFee.Value * Fields!Unit.Value), true, false) ,
"Red", "")
Can someone please help.
Method 1:
Try something like this.
=IIF(Fields!Year.Value = Year(now)
and
SUM(iif(Fields!Year.Value = Year(now), Fields!CalculatedFee.Value * Fields!Unit.Value, 0.0), "YourDataSetName" )
< SUM(iif(Fields!Year.Value = Year(now)-1, Fields!CalculatedFee.Value * Fields!Unit.Value, 0.0), "YourDataSetName" )
,"Red", Nothing)
If you specify SUM(Fields!CalculatedFee.Value * Fields!Unit.Value) SSRS will sum it up in your current dataset scope.
Method 2:
It depends on how your dataset is laid out. You may be able to use lookup function.
=IIF(Fields!Year.Value = Year(now)
and
Lookup(Year(now), Fields!Year.Value, Fields!CalculatedFee.Value * Fields!Unit.Value, "YourDataSetName" )
< Lookup(Year(now)-1, Fields!Year.Value, Fields!CalculatedFee.Value * Fields!Unit.Value, "YourDataSetName" )
,"Red", Nothing)
Method 3:
If you can change the report output to show 2013 first and 2014 next. In that case you can use Previous function to set the color.
Method 4:
You can change the dataset query to set a flag for color. In other words do your compaision in the query and use the flag to set the color in report.

Matplotlib table: individual column width

Is there a way to specify the width of individual columns in a matplotlib table?
The first column in my table contains just 2-3 digit IDs, and I'd like this column to be smaller than the others, but I can't seem to get it to work.
Let's say I have a table like this:
import matplotlib.pyplot as plt
fig = plt.figure()
table_ax = fig.add_subplot(1,1,1)
table_content = [["1", "Daisy", "ill"],
["2", "Topsy", "healthy"]]
table_header = ('ID', 'Name','Status')
the_table = table_ax.table(cellText=table_content, loc='center', colLabels=table_header, cellLoc='left')
fig.show()
(Never mind the weird cropping, it doesn't happen in my real table.)
What I've tried is this:
prop = the_table.properties()
cells = prop['child_artists']
for cell in cells:
text = cell.get_text()
if text == "ID":
cell.set_width(0.1)
else:
try:
int(text)
cell.set_width(0.1)
except TypeError:
pass
The above code seems to have zero effect - the columns are still all equally wide. (cell.get_width() returns 0.3333333333, so I would think that width is indeed cell-width... so what am I doing wrong?
Any help would be appreciated!
I've been searching the web over and over again looking for similar probelm sollutions. I've found some answers and used them, but I didn't find them quite straight forward. By chance I just found the table method get_celld when simply trying different table methods.
By using it you get a dictionary where the keys are tuples corresponding to table coordinates in terms of cell position. So by writing
cellDict=the_table.get_celld()
cellDict[(0,0)].set_width(0.1)
you will simply adress the upper left cell. Now looping over rows or columns will be fairly easy.
A bit late answer, but hopefully others may be helped.
Just for completion. The column header starts with (0,0) ... (0, n-1). The row header starts with (1,-1) ... (n,-1).
---------------------------------------------
| ColumnHeader (0,0) | ColumnHeader (0,1) |
---------------------------------------------
rowHeader (1,-1) | Value (1,0) | Value (1,1) |
--------------------------------------------
rowHeader (2,-1) | Value (2,0) | Value (2,1) |
--------------------------------------------
The code:
for key, cell in the_table.get_celld().items():
print (str(key[0])+", "+ str(key[1])+"\t"+str(cell.get_text()))
Condition text=="ID" is always False, since cell.get_text() returns a Text object rather than a string:
for cell in cells:
text = cell.get_text()
print text, text=="ID" # <==== here
if text == "ID":
cell.set_width(0.1)
else:
try:
int(text)
cell.set_width(0.1)
except TypeError:
pass
On the other hand, addressing the cells directly works: try cells[0].set_width(0.5).
EDIT: Text objects have an attribute get_text() themselves, so getting down to a string of a cell can be done like this:
text = cell.get_text().get_text() # yup, looks weird
if text == "ID":

Anim Plot Updating

I am trying to find maximum values of a sinusoidal and show it in a subplot. And trying to update it like an animation. But the subplot of the maximum values gives all zero values. When I print the array it is not zeroes. I think it is not updating y values. I couldn't figure out the reason. Any help would be kindly appreciated.
I will put my code it is executable:
from pylab import *
import time
ion()
fs = 1e6
Ts = 1/fs
SNR=10
sinfreq=2*pi*1e5
pack= 512
t = Ts*arange(0,pack)
f = fs*(arange(0,pack)-pack/2)/pack
max_y = zeros (len(t))
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
subplot(211)
line1, = plot(y)
subplot(212)
line2, = plot(max_y)
for i1 in arange(1,1000):
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
line1.set_ydata(y)
mk=0
for mk in range(0,len(y)):
if y[mk] > max_y[mk]:
max_y[mk] = y[mk]
print max_y
line2.set_ydata(max_y)
draw()
waitforbuttonpress(timeout=0.5)
You've forgotten an indent in the second for loop.
That should actually give you an IndentationError, so I don't understand how you can say that the program is executable (in fact, I edited your entry to remove the left-over "enter code here" statement; if you had checked and copy-pasted your entry, you'd probably found both mistakes).
But, are you sure you don't want simply
max_y[:] = max(y)
instead of that for loop?
Ok I have found the solution incidentally, I don't know the reason but I update my max_y plot any other value firstly then do my real update, then the plot shows my changes. Other than this it is not showing. I try with different for loops they are ploting with one update but for my loop it wanted to update twice.
I have also add set_ylim to see better the limits. I put stars to places that I have changed. I am putting the new code also. I wish it will help people that have the same problem.
from pylab import *
import time
ion()
fs = 1e6
Ts = 1/fs
SNR=10
sinfreq=2*pi*1e5
pack= 512
t = Ts*arange(0,pack)
f = fs*(arange(0,pack)-pack/2)/pack
max_y = zeros (len(t))
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
subplot(211)
line1, = plot(y)
sub2=subplot(212) #****
line2, = plot(max_y)
for i1 in arange(1,1000):
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
line1.set_ydata(y)
mk=0
for mk in range(0,len(y)):
if y[mk] > max_y[mk]:
max_y[mk] = y[mk]
#print max_y
line2.set_ydata(zeros(len(max_y)))#****
line2.set_ydata(max_y)
sub2.set_ylim(min(max_y),max(max_y)) #****
draw()
waitforbuttonpress(timeout=0.5)