How to Split the box plot of a variable with several levels - boxplot

How can I modify this code to make the space between second and third levels on the box plot. I mean, I want to spit the box plot into two section, a and b on right side and c on the left side.
library(ggplot2)
df <- data.frame(group=sample(c("a","b","c"),100,replace=T),x=rnorm(100),y=rnorm(100)*rnorm(100))
xlabs <- paste(levels(df$group),"\n(N=",table(df$group),")",sep="")
ggplot(df,aes(x=group,y=x,color=group))+geom_boxplot()+scale_x_discrete(labels=xlabs)

Try to add new variable for facetting in ggplot.
df$facets <- ifelse(df$group == "a" | df$group == "b", "ab", "c")
Now plot with facet_grid and modified scale_x_dsicrete.
ggplot(df,aes(x=group,y=x,color=group)) +
geom_boxplot()+
facet_grid(~ facets, scales = "free_x", space = "free_x") +
scale_x_discrete(breaks = levels(df$group), labels = xlabs)
If your question has been answered, please make sure to accept an answer for further references.

Related

Unmerge and Assign Values Only Vertically or Horizontally Openpyxl

Using the answer provided by aka863 here: How to split merged Excel cells with Python?
I can unmerge, fill values and copy the styling. My questions is how to make the value assigning/filling process configurable.
I want the user to be able to choose whether the values will be filled vertically/horizontally.
I have tried changing the last loop where we assign the top_left_cell_values to unmerged cells. However I couldn't find a way to make it horizontal/vertical configurable. (I'm planning to use radio buttons and tkinter for this)
Its certainly possible to have the code de-merge cells and fill cells in whichever direction, vertically or horizontally regardless of which way the merge was originally. Or not fill at all, so only the top left cell retains the 'value' of the previously merged cells, which is default on unmerge.
Changing the direction of the fill requires some change and re-calculation on the max row and column values in the iter_rows loop, but is simple enough.
However it seems in your last comment you just want to give the user the option to fill or not fill on horizontal merges. In that case you just need to ask the question, and then run the iter_rows loop only if the response is yes.
The code sample below is based on the answer referenced question.
I'm assuming only single line horizontal merges since you dont mention what if anything should be done with vertical merges in the comment.
The code does initially check and indicate the merge direction either vertically or horizontally so it can be included take some action if a merge is vertical.
On code run after displaying the range and direction of the merge, the question is asked to fill, yes or no. If yes the cells are de-merged and all cells filled with the top left cell value using the iter_rows loop. If answer no then the cells are just de-merged.
from openpyxl import load_workbook
from openpyxl.utils.cell import range_boundaries
wb = load_workbook(filename='foo.xlsx')
st = wb['Sheet1']
mcr_coord_list = [mcr.coord for mcr in st.merged_cells.ranges]
direction_dict = {'v': 'vertical', 'h': 'horizontal'}
for mcr in mcr_coord_list:
print('---------------------------------------------------\n')
merge_direction = ''
min_col, min_row, max_col, max_row = range_boundaries(mcr)
top_left_cell_value = st.cell(row=min_row, column=min_col).value
if min_col == max_col:
merge_direction = 'v'
elif min_row == max_row:
merge_direction = 'h'
print(f"The cell range {mcr} is merged {direction_dict[merge_direction]}ly with the data '{top_left_cell_value}'")
while True:
demerge_fill = input('Do you want the de-merge to fill all cells(y|n)? ')
if demerge_fill.lower() in ["y", "n"]:
break
else:
print('Invalid response')
st.unmerge_cells(mcr)
if demerge_fill == 'y':
for row in st.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
else:
print(f"Only the top left cell {mcr.split(':')[0]} will contain the data!")
wb.save('merged_tmp.xlsx')

Leaflet - How to display a smaller map inside a larger map (with tiles)?

I have the following problem: I have a world map, which should serve as a base map and a map of a certain region (e.g. Germany). Both are available in tile format. I would like to display the regional map above the world map at the correct coordinate position. And here's the problem: I can display the region map above the world map, but I don't know how to position it correctly.
Anybody got any advice here?
EDIT
Here I create a simple base map on which I want to display data later. Afterwards I divide the map into tiles with gdal2tiles.py.
map = Basemap( projection='merc', resolution='c',
lat_0=51., lon_0=10.,
urcrntlat=85.051, urcrnrlon=179.000,
llcrnrlat=85.051, llcrnrlon=-179.000
)
map.bluemarble()
filename='map.png'
dirname = 'tiles'
plt.savefig ( filename )
minZoom = 0
maxZoom = 4
subprocess.check_output( "gdal2tiles.py --leaflet --profile=raster --zoom=" + str(minZoom) + "-" + str(maxZoom) + " " + filename + " " + dirname,
stderr=subprocess.STDOUT,
shell=True,
)
Here I use the functions from tilenames.py to determine where the tile should be.
import tilenames as tn
for z in range(minZoom, maxZoom):
x, y = tn.tileXV(lat, lon, z)
s,w,n,e = tn.tileEdges(x, y, z)
print("z={:d}: x={:d} y={:d} --> urcrnrlat={:.3f}, urcrnrlon={:.3f}, llcrnrlat={:.3f}, llcrnrlat={:.3f}".format(z,x,y,n,e,s,w))
See the section titled "minimaps and synced maps" in the Leaflet plugins list.
Sounds like your use case is well covered by some plugins in that list, specifically either Leaflet.Minimap or Leaflet.Sync. Please check the documentation and examples for those, and have a quick look at the other plugins in that list.

How to change background color for each two rows in SSRS in a group

How can I write the expression in order to change background color for each two rows in SSRS?
I need something like that:
I tried expression
=IIF(Fields!Type.Value="2016 Submitted" , "LightBlue",
IIF(Fields!Type.Value="2015 Submitted" , "LightBlue",
Nothing))
But because some months dont have values it looks like this:
If I try this expression I get below:
=IIF(RunningValue(Fields!Count.Value, CountDistinct, Nothing) MOD 2 = 1, "White", "PaleTurquoise")
Dance-Henry I tried your code
=IIF(RowNumber(Nothing) Mod 4 = 1 or RowNumber(Nothing) Mod 4 = 2, "Aqua","White")
and this is what i got:
You can select the row in design pane and press F4 to setup property BackgroundColor as =IIF(RowNumber(Nothing) Mod 4 = 1 or RowNumber(Nothing) Mod 4 = 2, "Aqua","White")
Captures are attached. Do it accordingly.
RESULT is something like this
After going thru the link https://blogs.msdn.microsoft.com/chrishays/2004/08/30/green-bar-matrix/
Tested and it works well for the Green Bar Effect for Matrix. I will show it step by step here as for later reference.
Step 1: Create the Matrix and add one more column under the innermost row grouping in your matrix. (ColorNameTextbox here)
Step 2: Select the textbox of ColorNameTextbox and press F4 to setup BackgroundColor property as =Value shown below.
Step 3: Select the textbox of Matrix cell and press F4 to setup BackgroundColor property as =ReportItems!ColorNameTextbox.Value shown below.
Step 4: Drag the inner grouping header (ColorNameTextbox) to be as narrow as possible.
Step 5: Preview Pane to check the result.
If you could add a hidden color_group column and populate it with a new number at each point you want to change the color (in your case 1,1,2,2,3,3,4,4) then you could use something like the following (which works for varying size groups):
IIF(RunningValue(Fields!color_group.Value, CountDistinct, Nothing) MOD 2 = 1, "White", "PaleTurquoise")
I had a similar problem where I could not come up with alternating rows because my data has Column Groups that were the RowNumber(Nothing) method to fail. Learning from all the other posts here this is how I resolved it in steps.
I added the following code into the report properties, that provides a function to get the row number, each time it is called. The function increments the row count each time it is called. >>Right click space around the report >> Properties >> Code. Alternatively go to Code Properties Window, when the report is selected.
Add the following lines:
Public Row_Sum As Decimal = 0
Public Function Lookup_Sum( ) As integer
Row_Sum = Row_Sum + 1
Return Row_Sum
End Function
I added a new column at the beginning of the rows called No. that would calculate and show the row number.Right click the first column >>Insert Column>>Inside Group-Left.
On the expression for the new report add this line of code. Also take a note of the name of the TextBox that will have the No. Value. It will be needed in the next step. In my case the TextBox is called TextBox6 (Properties Window). >>Right Click Cell>>Expression.
Add the code:
=Code.Lookup_Sum()
I highlighted the entire row and went to the Background property and added the following expression to compute the row number.
Add the code(TextBox6 is the name Textbox name noted above):
=IIF(VAL(ReportItems!Textbox6.Value) MOD 2, "LIGHTBLUE", "WHITE")

How to align a label versus its content?

I have a label (e.g. "A list of stuff") and some content (e.g. an actual list). When I add all of this to a PDF, I get:
A list of stuff: test A, test B, coconut, coconut, watermelons, apple, oranges, many more
fruites, carshow, monstertrucks thing
I want to change this so that the content is aligned like this:
A list of stuff: test A, test B, coconut, coconut, watermelons, apple, oranges, many more
fruites, carshow, monstertrucks thing, everything is startting on the
same point in the line now
In other words: I want the content to be aligned so that it every line starts at the same X position, no matter how many items are added to the list.
There are many different ways to achieve what you want: Take a look at the following screen shot:
This PDF was created using the IndentationOptions example.
In the first option, we use a List with the label ("A list of stuff: ") as the list symbol:
List list = new List();
list.setListSymbol(new Chunk(LABEL));
list.add(CONTENT);
document.add(list);
document.add(Chunk.NEWLINE);
In the second option, we use a paragraph of which we use the width of the LABEL as indentation, but we change the indentation of the first line to compensate for that indentation.
BaseFont bf = BaseFont.createFont();
Paragraph p = new Paragraph(LABEL + CONTENT, new Font(bf, 12));
float indentation = bf.getWidthPoint(LABEL, 12);
p.setIndentationLeft(indentation);
p.setFirstLineIndent(-indentation);
document.add(p);
document.add(Chunk.NEWLINE);
In the third option, we use a table with columns for which we define an absolute width. We use the previously calculated width for the first column, but we add 4, because the default padding (left and right) of a cell equals 2. (Obviously, you can change this padding.)
PdfPTable table = new PdfPTable(2);
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.setTotalWidth(new float[]{indentation + 4, 519 - indentation});
table.setLockedWidth(true);
table.addCell(LABEL);
table.addCell(CONTENT);
document.add(table);
There may be other ways to achieve the same result, and you can always tweak the above options. It's up to you to decide which option fits best in your case.

World.QueryAABB giving incorrect results in libgdx

I'm trying to implement mouse selection for my game. When I QueryAABB it looks like it's treating objects much larger than they really are.
Here's what's going on in the image
The blue box is an actor containing a body that I'd like to select
The outline on the blue box is drawn by Box2DDebugRenderer
The mouse selects a region on the screen (white box), this is entirely graphical
The AABB is converted to meters and passed to QueryAABB
The callback was called for the blue box and turned it red
The green outline left behind is a separate body to check if my conversions were correct, this is not used for the actual selection process
It seems to be connected to my meter size, the larger it is, the more inaccurate the result is. At 1 meter = 1 pixel it works perfectly.
Meter conversions
val MetersToPixels = 160f
val PixelsToMeters = 1/MetersToPixels
def toMeters(n: Float) = n * PixelsToMeters
def toPixels(n: Float) = n * MetersToPixels
In the image I'm using MetersToPixels = 160f so the inaccuracy is more visible, but I really want MetersToPixels = 16f.
Relevant selection code
val x1 = selectPos.x
val y1 = selectPos.y
val x2 = getX
val y2 = getY + getHeight
val (l,r) =
if (x2 < x1)
(x2,x1)
else
(x1,x2)
val (b,t) =
if (y2 < y1)
(y2,y1)
else
(y1,y2)
world.QueryAABB(selectCallback, toMeters(l),toMeters(b), toMeters(r),toMeters(t))
This code is inside the act method of my CursorActor class. And selectPos represents the initial point where the use pressed down the left mouse button and getX and getY are Actor methods giving the current position. The next bit sorts them because they might be out of order. Then they are converted to meters because they are all in pixel units.
selectCallback: QueryCallback
override def reportFixture(fixture: Fixture): Boolean = {
fixture.getBody.getUserData match {
case selectable: Selectable =>
selected += selectable
true
case _ => true
}
}
Selectable is a trait that sets a boolean flag internally after the query which helps determines the color of the blue box. And selected is a mutable.HashSet[Selectable] defined inside of CursorActor.
Other things possibly worth noting
I'm new to libgdx and box2d.
The camera is scaled x2
My Box2DDebugRenderer uses the camera's combined matrix multiplied by MetersToPixels
From what I was able to gather, QueryAABB is naturally inaccurate for optimization. However, I've hit a roadblock with libgdx because it doesn't have any publicly visible function like b2testOverlap and from what I understand, there's no plan for there to be one any time soon.
I think my best solution would probably be to use jbox2d and pretend that libgdx's physics implementation doesn't exist.
Or as noone suggested I could add it to libgdx myself.
UPDATE
I decided to go with a simple solution of gathering the vertices from the fixture's shape and using com.badlogic.gdx.math.Intersector against the vertices of the selection. It works I guess. I may stop using QueryAABB all together if I decide to switch to using a sensor for the select box.