基本图形和ggplot2之间的直方图binwidth(in)一致性

时间:2017-02-16 05:01:27

标签: r ggplot2 histogram

我遇到了以下情况......

以下代码生成2个相同的直方图:

library(ggplot2)
data("diamonds")    
ggplot(diamonds, aes(x=price)) + geom_histogram(binwidth=1000)
qplot(price, data = diamonds, binwidth = 1000)

但是,我不明白他们是如何得出左边的第一个条/箱,事实上,整个直方图对我来说似乎不对。 enter image description here

另一方面:

hist(diamonds$price,breaks = seq(0,20000, by=1000))

生成以下图表,这对我来说是正确的: enter image description here

为了验证数据,我运行了这段代码:

br = seq(0,20000,by=1000)

ranges = paste(head(br,-1), br[-1], sep=" - ")
freq = hist(diamonds$price, breaks = br, include.lowest=TRUE, plot=FALSE)

data.frame(range = ranges, frequency = freq$counts)

它产生:

           range frequency
1       0 - 1000     14524
2    1000 - 2000      9683
3    2000 - 3000      6129
4    3000 - 4000      4225
5    4000 - 5000      4665
...

那么ggplotqplot中的第一个bar / bin来自哪里?

1 个答案:

答案 0 :(得分:3)

ggplot直方图条中心位于0,1000,2000等,而基本直方图条中心位于500,1500,2500等。要检查这一点,请将每个直方图中的条形数与表计数进行比较。我们明确地设置了休息时间。

(-500,500]       (500,1.5e+03]   (1.5e+03,2.5e+03]   (2.5e+03,3.5e+03]   (3.5e+03,4.5e+03] 
      1749               18261                7532                4958                4535
etc.
theme_set(theme_classic())
ggplot(diamonds, aes(x=price)) + 
  geom_histogram(binwidth=1000, fill="grey80", colour="black", lwd=0.2) +
  stat_bin(binwidth=1000, geom="text", aes(label=..count..),
           position=position_stack(vjust=0.5), size=3)
freq = hist(diamonds$price)$counts
tab = unname(table(cut(diamonds$price, breaks=seq(0,19000,1000))))

cbind(freq, tab)

enter image description here

对于基本直方图:

       freq   tab
 [1,] 14524 14524
 [2,]  9683  9683
 [3,]  6129  6129
 [4,]  4225  4225
 [5,]  4665  4665
 [6,]  3163  3163
 [7,]  2278  2278
 [8,]  1668  1668
 [9,]  1307  1307
[10,]  1076  1076
[11,]   934   934
[12,]   825   825
[13,]   701   701
[14,]   603   603
[15,]   504   504
[16,]   513   513
[17,]   425   425
[18,]   405   405
[19,]   312   312
center

要在ggplot直方图中获得相同的中断,除了binwidth之外,您还可以使用ggplot(diamonds, aes(x=price)) + geom_histogram(binwidth=1000, center=500, fill="grey80", colour="black", lwd=0.2) + stat_bin(binwidth=1000, center=500, geom="text", aes(label=..count..), position=position_stack(vjust=0.5), size=3) 参数:

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {

ImageView choosenImageView;
Button choosePicture;
Button savePicture;

Bitmap bmp;
Bitmap bmp1;
Bitmap alteredBitmap;
Canvas canvas;
Paint paint;
Matrix matrix;
float downx = 0;
float downy = 0;
float upx = 0;
float upy = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    choosenImageView = (ImageView) this.findViewById(R.id.ChoosenImageView);
    choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton);
    //savePicture = (Button) this.findViewById(R.id.SavePictureButton);

    //savePicture.setOnClickListener(this);
    choosePicture.setOnClickListener(this);
    choosenImageView.setOnTouchListener(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {

    if (v == choosePicture) {
        Intent choosePictureIntent = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        Log.d("Started","->");
        startActivityForResult(choosePictureIntent, 0);
    } else if (v == savePicture) {

        if (alteredBitmap != null) {
            ContentValues contentValues = new ContentValues(3);
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "Draw On Me");

            Uri imageFileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            try {

                OutputStream imageFileOS = getContentResolver().openOutputStream(imageFileUri);
                alteredBitmap.compress(Bitmap.CompressFormat.JPEG, 90, imageFileOS);
                Toast t = Toast.makeText(this, "Saved!", Toast.LENGTH_SHORT);
                t.show();

            } catch (Exception e) {
                Log.v("EXCEPTION", e.getMessage());
            }
        }
    }
}

protected void onActivityResult(int requestCode, int resultCode,
                                Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (resultCode == RESULT_OK) {
        Uri imageFileUri = intent.getData();
        try {
            BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                    imageFileUri), null, bmpFactoryOptions);

            bmpFactoryOptions.inSampleSize = 3; //calculateInSampleSize(options, reqWidth, reqHeight);
            //bmpFactoryOptions.inSampleSize = calculateInSampleSize(bmpFactoryOptions, choosenImageView.getWidth(), choosenImageView.getHeight());
            Log.i("inSampleSize","->"+calculateInSampleSize(bmpFactoryOptions, choosenImageView.getWidth(), choosenImageView.getHeight()));

            bmpFactoryOptions.inJustDecodeBounds = false;
            bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                    imageFileUri), null, bmpFactoryOptions);

            Log.d("Bitmap","crseated");
            alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
                    .getHeight(), bmp.getConfig());
            canvas = new Canvas(alteredBitmap);

            //choosenImageView.draw(canvas);
            /*Bitmap result =Bitmap.createBitmap(alteredBitmap,choosenImageView.getLeft()+10, choosenImageView.getTop()+50,
                    choosenImageView.getWidth()-20, choosenImageView.getHeight()-100);*/
    //        alteredBitmap.recycle();

            paint = new Paint();
            paint.setColor(Color.GREEN);
            paint.setStrokeWidth(10);
            matrix = new Matrix();
            canvas.drawBitmap(bmp, matrix, paint);

            choosenImageView.setImageBitmap(alteredBitmap);
            choosenImageView.setOnTouchListener(this);
        } catch (Exception e) {
            Log.v("ERROR", e.toString());
        }
    }
}

//Given the bitmap size and View size calculate a subsampling size (powers of 2)
static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) {
    int inSampleSize = 1;   //Default subsampling size
    // See if image raw height and width is bigger than that of required view
    if (options.outHeight > reqHeight || options.outWidth > reqWidth) {
        //bigger
        final int halfHeight = options.outHeight / 2;
        final int halfWidth = options.outWidth / 2;
        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

@Override
public boolean onTouch(View view, MotionEvent event) {
    int action = event.getAction();
    switch (action) {
        case MotionEvent.ACTION_DOWN:
            downx = event.getX();
            downy = event.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            upx = event.getX();
            upy = event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            choosenImageView.invalidate();
            downx = upx;
            downy = upy;
            break;
        case MotionEvent.ACTION_UP:
            upx = event.getX();
            upy = event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            choosenImageView.invalidate();
            break;
        case MotionEvent.ACTION_CANCEL:
            break;
        default:
            break;
    }
    return true;
}
}

enter image description here